commonMain.com.bkahlert.kommons.factories.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kommons-core-jvm Show documentation
Show all versions of kommons-core-jvm Show documentation
Kommons Core is a Kotlin Multiplatform Library that offers shared features for all Kommons modules.
package com.bkahlert.kommons
import com.bkahlert.kommons.Converter.Converter1
import com.bkahlert.kommons.Converter.Converter2
import com.bkahlert.kommons.Converter.Converter3
import com.bkahlert.kommons.Creator.Creator1
import com.bkahlert.kommons.Creator.Creator2
import com.bkahlert.kommons.Creator.Creator3
import com.bkahlert.kommons.Parser.Companion.parser
import kotlin.reflect.KClass
/**
* Factory that can create a [T] object.
* @see Creator1
* @see Creator2
* @see Creator3
*/
public sealed interface Creator {
/**
* Factory that can create a [T] object of a [P1] object.
*
* *Intended to be implemented by delegation by a companion object
* using [creator] to offer
* a [of] factory method and
* a [ofOrNull] factory method.*
*
* @see Method Naming Convention
*/
public interface Creator1 : Creator {
/** Returns an object of type [T] created of the [P1] object, or `null` otherwise. */
public fun ofOrNull(obj: P1): T? = kotlin.runCatching { of(obj) }.getOrNull()
/** Returns an object of type [T] created of the [P1] object, or throws a [CreationException] otherwise. */
public fun of(obj: P1): T
}
/**
* Factory that can create a [T] object of a [P1] and a [P2] object.
*
* *Intended to be implemented by delegation by a companion object
* using [creator] to offer
* a [of] factory method and
* a [ofOrNull] factory method.*
*
* @see Method Naming Convention
*/
public interface Creator2 : Creator {
/** Returns an object of type [T] created of the [P1] and [P2] object, or `null` otherwise. */
public fun ofOrNull(obj1: P1, obj2: P2): T? = kotlin.runCatching { of(obj1, obj2) }.getOrNull()
/** Returns an object of type [T] created of the [P1] and [P2] object, or throws a [CreationException] otherwise. */
public fun of(obj1: P1, obj2: P2): T
}
/**
* Factory that can create a [T] object of a [P1], a [P2] and a [P3] object.
*
* *Intended to be implemented by delegation by a companion object
* using [creator] to offer
* a [of] factory method and
* a [ofOrNull] factory method.*
*
* @see Method Naming Convention
*/
public interface Creator3 : Creator {
/** Returns an object of type [T] created of the [P1], [P2], and [P3] object, or `null` otherwise. */
public fun ofOrNull(obj1: P1, obj2: P2, obj3: P3): T? = kotlin.runCatching { of(obj1, obj2, obj3) }.getOrNull()
/** Returns an object of type [T] created of the [P1], [P2], and [P3] object, or throws a [CreationException] otherwise. */
public fun of(obj1: P1, obj2: P2, obj3: P3): T
}
public companion object {
/** Returns a [Creator1] that can create a [T] object of a [P1] object using the specified [createOrNull]. */
public inline fun creator(crossinline createOrNull: (P1) -> T?): Creator1 = object : Creator1 {
override fun of(obj: P1): T = kotlin.runCatching {
createOrNull(obj) ?: throw CreationException(T::class, obj)
}.getOrElse {
if (it is CreationException) throw it
throw throw CreationException(T::class, it, obj)
}
}
/** Returns a [Creator2] that can create a [T] object of a [P1] and a [P2] object using the specified [createOrNull]. */
public inline fun creator(crossinline createOrNull: (P1, P2) -> T?): Creator2 = object : Creator2 {
override fun of(obj1: P1, obj2: P2): T = kotlin.runCatching {
createOrNull(obj1, obj2) ?: throw CreationException(T::class, obj1, obj2)
}.getOrElse {
if (it is CreationException) throw it
throw throw CreationException(T::class, it, obj1, obj2)
}
}
/** Returns a [Creator3] that can create a [T] object of a [P1], a [P2], and a [P3] object using the specified [createOrNull]. */
public inline fun creator(crossinline createOrNull: (P1, P2, P3) -> T?): Creator3 =
object : Creator3 {
override fun of(obj1: P1, obj2: P2, obj3: P3): T = kotlin.runCatching {
createOrNull(obj1, obj2, obj3) ?: throw CreationException(T::class, obj1, obj2, obj3)
}.getOrElse {
if (it is CreationException) throw it
throw throw CreationException(T::class, it, obj1, obj2, obj3)
}
}
}
/** Exception thrown by a [Creator] when creation fails. */
public class CreationException(
message: String,
/** Optional cause of this exception. */
cause: Throwable? = null,
) : IllegalArgumentException(message, cause) {
/** Creates a new creator exception for the specified [objects], the specified [type], and the optional [cause]. */
public constructor(
type: KClass<*>,
cause: Throwable? = null,
vararg objects: Any?,
) : this("Failed to create an instance of ${type.simpleName ?: type.toString()} of ${objects.joinToString { it.quoted }}", cause)
/** Creates a new creator exception for the specified [objects] and the specified [type]. */
public constructor(
type: KClass<*>,
vararg objects: Any?,
) : this(type, null, *objects)
}
}
/**
* Factory that can convert objects to a [T] object.
* @see Converter1
* @see Converter2
* @see Converter3
*/
public sealed interface Converter {
/**
* Factory that can convert a [P1] object to a [T] object.
*
* *Intended to be implemented by delegation by a companion object
* using [converter] to offer
* a [from] factory method and
* a [fromOrNull] factory method.*
*
* @see Method Naming Convention
*/
public interface Converter1 : Converter {
/** Returns an object of type [T] representing the converted [P1] object, or `null` otherwise. */
public fun fromOrNull(obj: P1): T? = kotlin.runCatching { from(obj) }.getOrNull()
/** Returns an object of type [T] representing the converted [P1] object, or throws a [ConversionException] otherwise. */
public fun from(obj: P1): T
}
/**
* Factory that can convert a [P1] and a [P2] object to a [T] object.
*
* *Intended to be implemented by delegation by a companion object
* using [converter] to offer
* a [from] factory method and
* a [fromOrNull] factory method.*
*
* @see Method Naming Convention
*/
public interface Converter2 : Converter {
/** Returns an object of type [T] representing the converted [P1] and [P2] object, or `null` otherwise. */
public fun fromOrNull(obj1: P1, obj2: P2): T? = kotlin.runCatching { from(obj1, obj2) }.getOrNull()
/** Returns an object of type [T] representing the converted [P1] and [P2] object, or throws a [ConversionException] otherwise. */
public fun from(obj1: P1, obj2: P2): T
}
/**
* Factory that can convert a [P1], a [P2], and a [P3] object to a [T] object.
*
* *Intended to be implemented by delegation by a companion object
* using [converter] to offer
* a [from] factory method and
* a [fromOrNull] factory method.*
*
* @see Method Naming Convention
*/
public interface Converter3 : Converter {
/** Returns an object of type [T] representing the converted [P1], [P2], and [P3] object, or `null` otherwise. */
public fun fromOrNull(obj1: P1, obj2: P2, obj3: P3): T? = kotlin.runCatching { from(obj1, obj2, obj3) }.getOrNull()
/** Returns an object of type [T] representing the converted [P1], [P2], and [P3] object, or throws a [ConversionException] otherwise. */
public fun from(obj1: P1, obj2: P2, obj3: P3): T
}
public companion object {
/** Returns a [Converter1] that can convert a [P1] object to a [T] object using the specified [convertOrNull]. */
public inline fun converter(crossinline convertOrNull: (P1) -> T?): Converter1 = object : Converter1 {
override fun from(obj: P1): T = kotlin.runCatching {
convertOrNull(obj) ?: throw ConversionException(T::class, obj)
}.getOrElse {
if (it is ConversionException) throw it
throw throw ConversionException(T::class, it, obj)
}
}
/** Returns a [Converter2] that can convert a [P1] and [P2] object to a [T] object using the specified [convertOrNull]. */
public inline fun converter(crossinline convertOrNull: (P1, P2) -> T?): Converter2 =
object : Converter2 {
override fun from(obj1: P1, obj2: P2): T = kotlin.runCatching {
convertOrNull(obj1, obj2) ?: throw ConversionException(T::class, obj1, obj2)
}.getOrElse {
if (it is ConversionException) throw it
throw throw ConversionException(T::class, it, obj1, obj2)
}
}
/** Returns a [Converter3] that can convert a [P1], a [P2], and a [P3] object to a [T] object using the specified [convertOrNull]. */
public inline fun converter(crossinline convertOrNull: (P1, P2, P3) -> T?): Converter3 =
object : Converter3 {
override fun from(obj1: P1, obj2: P2, obj3: P3): T = kotlin.runCatching {
convertOrNull(obj1, obj2, obj3) ?: throw ConversionException(T::class, obj1, obj2, obj3)
}.getOrElse {
if (it is ConversionException) throw it
throw throw ConversionException(T::class, it, obj1, obj2, obj3)
}
}
}
/** Exception thrown by a [Converter] when conversion fails. */
public class ConversionException(
message: String,
/** Optional cause of this exception. */
cause: Throwable? = null,
) : IllegalArgumentException(message, cause) {
/** Creates a new converter exception for the specified [objects], the specified [type], and the optional [cause]. */
public constructor(
type: KClass<*>,
cause: Throwable? = null,
vararg objects: Any?,
) : this("Failed to convert ${objects.joinToString { it.quoted }} to an instance of ${type.simpleName ?: type.toString()}", cause)
/** Creates a new converter exception for the specified [objects] and the specified [type]. */
public constructor(
type: KClass<*>,
vararg objects: Any?,
) : this(type, null, *objects)
}
}
/**
* Parser than can parse a string into a [T] object.
*
* *Intended to be implemented by delegation by a companion object
* using [parser] to offer
* a [parse] factory method and
* a [parseOrNull] factory method.*
*
* @see Method Naming Convention
*/
public interface Parser {
/** Returns an object of type [T] representing the parsed [text], or `null` otherwise. */
public fun parseOrNull(text: CharSequence): T? = kotlin.runCatching { parse(text) }.getOrNull()
/** Returns an object of type [T] representing the parsed [text], or throws a [ParsingException] otherwise. */
public fun parse(text: CharSequence): T
public companion object {
/** Returns a [Parser] that can parse a string into a [T] object using the specified [parse]. */
public inline fun parser(
crossinline parse: (CharSequence) -> T?,
): Parser = object : AbstractParser(T::class) {
override fun parseText(text: CharSequence): T? = parse.invoke(text)
}
}
}
/** Exception thrown by a [Parser] when parsing fails. */
public class ParsingException(
message: String,
/** Optional cause of this exception. */
cause: Throwable? = null,
) : IllegalArgumentException(message, cause) {
/** Creates a new parse exception for the specified [string], the specified [type], and the optional [cause]. */
public constructor(
string: CharSequence,
type: KClass<*>,
cause: Throwable? = null,
) : this("Failed to parse ${string.quoted} into an instance of ${type.simpleName ?: type.toString()}", cause)
}
/**
* Provides a skeletal implementation of the [Parser] interface.
*/
public abstract class AbstractParser(
private val kClass: KClass,
) : Parser {
protected abstract fun parseText(text: CharSequence): T?
override fun parse(text: CharSequence): T = kotlin.runCatching {
parseText(text) ?: throw ParsingException(text, kClass)
}.getOrElse {
if (it is ParsingException) throw it
throw throw ParsingException(text, kClass, it)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy