diff --git a/CHANGELOG.md b/CHANGELOG.md index 8951c64d5ef..19e43bf97fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ * `Pagination`: * `Common`: * Add several `optionallyReverse` functions +* `Common`: + * Changes in `Either`: + * Now `Either` uses `optionalT1` and `optionalT2` as main properties + * `Either#t1` and `Either#t2` are deprecated + * New extensions `Either#mapOnFirst` and `Either#mapOnSecond` ## 0.9.3 diff --git a/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Either.kt b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Either.kt index 0ec4dd895fd..2bf9c57ade4 100644 --- a/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Either.kt +++ b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Either.kt @@ -6,7 +6,7 @@ import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* /** - * Realization of this interface will contains at least one not null - [t1] or [t2] + * Realization of this interface will contains at least one not null - [optionalT1] or [optionalT2] * * @see EitherFirst * @see EitherSecond @@ -14,11 +14,19 @@ import kotlinx.serialization.encoding.* * @see Either.Companion.second * @see Either.onFirst * @see Either.onSecond + * @see Either.mapOnFirst + * @see Either.mapOnSecond */ @Serializable(EitherSerializer::class) sealed interface Either { + val optionalT1: Optional + val optionalT2: Optional + @Deprecated("Use optionalT1 instead", ReplaceWith("optionalT1")) val t1: T1? + get() = optionalT1.dataOrNull() + @Deprecated("Use optionalT2 instead", ReplaceWith("optionalT2")) val t2: T2? + get() = optionalT2.dataOrNull() companion object { fun serializer( @@ -93,25 +101,25 @@ class EitherSerializer( } /** - * This type [Either] will always have not nullable [t1] + * This type [Either] will always have not nullable [optionalT1] */ @Serializable data class EitherFirst( override val t1: T1 ) : Either { - override val t2: T2? - get() = null + override val optionalT1: Optional = t1.optional + override val optionalT2: Optional = Optional.absent() } /** - * This type [Either] will always have not nullable [t2] + * This type [Either] will always have not nullable [optionalT2] */ @Serializable data class EitherSecond( override val t2: T2 ) : Either { - override val t1: T1? - get() = null + override val optionalT1: Optional = Optional.absent() + override val optionalT2: Optional = t2.optional } /** @@ -124,23 +132,35 @@ inline fun Either.Companion.first(t1: T1): Either = EitherFirst inline fun Either.Companion.second(t2: T2): Either = EitherSecond(t2) /** - * Will call [block] in case when [Either.t1] of [this] is not null + * Will call [block] in case when [this] is [EitherFirst] */ inline fun > E.onFirst(block: (T1) -> Unit): E { - val t1 = t1 - t1 ?.let(block) + optionalT1.onPresented(block) return this } /** - * Will call [block] in case when [Either.t2] of [this] is not null + * Will call [block] in case when [this] is [EitherSecond] */ inline fun > E.onSecond(block: (T2) -> Unit): E { - val t2 = t2 - t2 ?.let(block) + optionalT2.onPresented(block) return this } +/** + * @return Result of [block] if [this] is [EitherFirst] + */ +inline fun Either.mapOnFirst(block: (T1) -> R): R? { + return optionalT1.mapOnPresented(block) +} + +/** + * @return Result of [block] if [this] is [EitherSecond] + */ +inline fun Either<*, T2>.mapOnSecond(block: (T2) -> R): R? { + return optionalT2.mapOnPresented(block) +} + inline fun Any.either() = when (this) { is T1 -> Either.first(this) is T2 -> Either.second(this)