All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.elide.core.api.Symbolic.kt Maven / Gradle / Ivy

/*
 * Copyright (c) 2023 Elide Ventures, LLC.
 *
 * Licensed under the MIT license (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   https://opensource.org/license/mit/
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under the License.
 */

@file:Suppress("RedundantVisibilityModifier")

package elide.core.api

/**
 * # Symbolic
 *
 * This interface maps a type [T] to the type to which it is applied; then, the adhering type's `companion object` (or
 * any sensible `object` related to type [T]) can implement [Symbolic.Resolver] to provide a means of resolving the
 * symbolic type to and from the concrete type.
 */
public interface Symbolic {
  /**
   * ## Symbolic: Unresolved
   *
   * Thrown when a symbol could not be resolved, usually via the [SealedResolver.unresolved] method; this method is
   * typically used from the resolver implementation only.
   */
  public class Unresolved internal constructor (internal val requested: Any) : IllegalStateException()

  /** Return the raw symbol represented by this type. */
  public val symbol: T

  /**
   * ## Symbolic: Resolver
   *
   * Specifies the expected interface for a resolver of a symbolic type [T] to a concrete type [Concrete]. Implementors
   * inheriting from this interface are allowed to produce `null` for a symbol; because of previous design decisions,
   * the [resolveSymbol] method (deprecated) will throw an [Unresolved] exception if the symbol cannot be resolved.
   *
   * A "sealed resolver" will throw an exception for all unresolved symbols.
   *
   * @param T Symbolic type which can be resolved, by this resolver, to a [Concrete] type.
   * @param Concrete Concrete type which can be resolved from type [T].
   * @see [SealedResolver]
   */
  public sealed interface Resolver where Concrete: Symbolic {
    /**
     * ### Resolve Symbol
     *
     * Resolve the given symbol to a concrete type [Concrete], or `null` if the symbol cannot be resolved.
     *
     * @param symbol Symbol to resolve to a [Concrete] type.
     * @return Concrete result, or `null`.
     */
    @Throws(Unresolved::class)
    public fun resolve(symbol: T): Concrete?

    /**
     * ### Resolve a Symbol (Strict)
     *
     * Resolves a symbol or throws [Unresolved]; this interface is a hold-over from previous versions of Elide, and it
     * is marked for deletion in the next release.
     *
     * @deprecated Use [resolve] instead.
     */
    @Throws(Unresolved::class)
    @Deprecated("Use `resolve` instead", replaceWith = ReplaceWith("resolve"))
    public fun resolveSymbol(symbol: T): Concrete = resolve(symbol) ?: throw Unresolved(symbol)
  }

  /**
   * ## Symbolic: Enumerated
   *
   * Describes a [Symbolic] type which is "closed" or "sealed" to an enumerated set of instances or symbols. Resolvers
   * which inherit from this type will throw an exception ([Unresolved]) for all unresolved symbols.
   *
   * @param T Symbolic type which can be resolved, by this resolver, to a [Concrete] type.
   * @param Concrete Concrete type which can be resolved from type [T].
   */
  public sealed interface Enumerated: Resolver where Concrete: Symbolic {
    /**
     * ### Resolve Symbol
     *
     * Resolve the given symbol to a concrete type [Concrete], or `null` if the symbol cannot be resolved.
     *
     * @throws Unresolved if the symbol cannot be resolved.
     * @param symbol Symbol to resolve to a [Concrete] type.
     * @return Concrete result, or `null`.
     */
    @Throws(Unresolved::class)
    override fun resolve(symbol: T): Concrete

    /**
     * ### Unresolved Symbol
     *
     * Create an [Unresolved] exception for the given symbol; it is up to the caller to throw the exception so that
     * stacktrace info remains accurate.
     *
     * @param requested Requested symbol which could not be resolved.
     * @return Unresolved exception.
     */
    public fun unresolved(requested: T): Unresolved = Unresolved(requested)
  }

  /**
   * ## Symbolic: Sealed Resolver
   *
   * Describes a [Symbolic] resolver which is "sealed" or "closed;" requests for symbols which cannot be resolved will
   * result in an exception ([Unresolved]).
   *
   * @param T Symbolic type which can be resolved, by this resolver, to a [Concrete] type.
   * @param Concrete Concrete type which can be resolved from type [T].
   */
  public interface SealedResolver: Enumerated where Concrete: Symbolic

  /**
   * ## Symbolic: Abstract Resolver
   *
   * Describes an advanced resolver which operates on a factory pattern, and which carries a name. Names of resolvers
   * implemented via this class are used in logging, errors, and other cosmetic places.
   *
   * @param T Symbolic type which can be resolved, by this resolver.
   */
  public abstract class AbstractResolver: SealedResolver> where T: Symbolic {
    /**
     * Return the name of this resolver.
     */
    public abstract val name: String
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy