Compare commits

...

6 Commits
0.7.4 ... 0.7.5

Author SHA1 Message Date
00acb9fddd add suppresses to the generated classes 2021-11-03 17:22:32 +06:00
de3d14dc41 solution of #109 2021-11-03 15:36:25 +06:00
67ff9cc9b3 update dependencies 2021-11-03 15:18:41 +06:00
af132103a0 start 0.7.5 and add either serializer 2021-11-02 12:43:59 +06:00
3b1124a804 fixes 2021-10-30 12:17:18 +06:00
f226c2dfd6 Merge pull request #106 from InsanusMokrassar/0.7.4
0.7.4
2021-10-29 13:57:58 +06:00
8 changed files with 131 additions and 18 deletions

View File

@@ -1,5 +1,16 @@
# Changelog # Changelog
## 0.7.5
* `Versions`:
* `Klock`: `2.4.6` -> `2.4.7`
* `Ktor`: `1.6.4` -> `1.6.5`
* `Common`:
* Type `Either` got its own serializer
* `FSM`:
* `Common`:
* Add opportunity for comfortable adding default state handler
## 0.7.4 ## 0.7.4
* `Common`: * `Common`:

View File

@@ -1,5 +1,10 @@
package dev.inmo.micro_utils.common package dev.inmo.micro_utils.common
import kotlinx.serialization.*
import kotlinx.serialization.builtins.serializer
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 - [t1] or [t2]
* *
@@ -10,16 +15,90 @@ package dev.inmo.micro_utils.common
* @see Either.onFirst * @see Either.onFirst
* @see Either.onSecond * @see Either.onSecond
*/ */
@Serializable(EitherSerializer::class)
sealed interface Either<T1, T2> { sealed interface Either<T1, T2> {
val t1: T1? val t1: T1?
val t2: T2? val t2: T2?
companion object companion object {
fun <T1, T2> serializer(
t1Serializer: KSerializer<T1>,
t2Serializer: KSerializer<T2>,
): KSerializer<Either<T1, T2>> = EitherSerializer(t1Serializer, t2Serializer)
}
}
class EitherSerializer<T1, T2>(
t1Serializer: KSerializer<T1>,
t2Serializer: KSerializer<T2>,
) : KSerializer<Either<T1, T2>> {
@ExperimentalSerializationApi
@InternalSerializationApi
override val descriptor: SerialDescriptor = buildSerialDescriptor(
"TypedSerializer",
SerialKind.CONTEXTUAL
) {
element("type", String.serializer().descriptor)
element("value", ContextualSerializer(Either::class).descriptor)
}
private val t1EitherSerializer = EitherFirst.serializer(t1Serializer, t2Serializer)
private val t2EitherSerializer = EitherSecond.serializer(t1Serializer, t2Serializer)
@ExperimentalSerializationApi
@InternalSerializationApi
override fun deserialize(decoder: Decoder): Either<T1, T2> {
return decoder.decodeStructure(descriptor) {
var type: String? = null
lateinit var result: Either<T1, T2>
while (true) {
when (val index = decodeElementIndex(descriptor)) {
0 -> type = decodeStringElement(descriptor, 0)
1 -> {
result = when (type) {
"t1" -> decodeSerializableElement(
descriptor,
1,
t1EitherSerializer
)
"t2" -> decodeSerializableElement(
descriptor,
1,
t2EitherSerializer
)
else -> error("Unknown type of either: $type")
}
}
CompositeDecoder.DECODE_DONE -> break
else -> error("Unexpected index: $index")
}
}
result
}
}
@ExperimentalSerializationApi
@InternalSerializationApi
override fun serialize(encoder: Encoder, value: Either<T1, T2>) {
encoder.encodeStructure(descriptor) {
when (value) {
is EitherFirst -> {
encodeStringElement(descriptor, 0, "t1")
encodeSerializableElement(descriptor, 1, t1EitherSerializer, value)
}
is EitherSecond -> {
encodeStringElement(descriptor, 0, "t2")
encodeSerializableElement(descriptor, 1, t2EitherSerializer, value)
}
}
}
}
} }
/** /**
* This type [Either] will always have not nullable [t1] * This type [Either] will always have not nullable [t1]
*/ */
@Serializable
data class EitherFirst<T1, T2>( data class EitherFirst<T1, T2>(
override val t1: T1 override val t1: T1
) : Either<T1, T2> { ) : Either<T1, T2> {
@@ -30,6 +109,7 @@ data class EitherFirst<T1, T2>(
/** /**
* This type [Either] will always have not nullable [t2] * This type [Either] will always have not nullable [t2]
*/ */
@Serializable
data class EitherSecond<T1, T2>( data class EitherSecond<T1, T2>(
override val t2: T2 override val t2: T2
) : Either<T1, T2> { ) : Either<T1, T2> {
@@ -44,7 +124,7 @@ inline fun <T1, T2> Either.Companion.first(t1: T1): Either<T1, T2> = EitherFirst
/** /**
* @return New instance of [EitherSecond] * @return New instance of [EitherSecond]
*/ */
inline fun <T1, T2> Either.Companion.second(t1: T1): Either<T1, T2> = EitherFirst(t1) inline fun <T1, T2> Either.Companion.second(t2: T2): Either<T1, T2> = EitherSecond(t2)
/** /**
* Will call [block] in case when [Either.t1] of [this] is not null * Will call [block] in case when [Either.t1] of [this] is not null
@@ -63,3 +143,9 @@ inline fun <T1, T2, E : Either<T1, T2>> E.onSecond(crossinline block: (T2) -> Un
t2 ?.let(block) t2 ?.let(block)
return this return this
} }
inline fun <reified T1, reified T2> Any.either() = when (this) {
is T1 -> Either.first<T1, T2>(this)
is T2 -> Either.second<T1, T2>(this)
else -> error("Incorrect type of either argument $this")
}

View File

@@ -6,7 +6,7 @@ import kotlin.reflect.KClass
* Default realization of [StatesHandler]. It will incapsulate checking of [State] type in [checkHandleable] and class * Default realization of [StatesHandler]. It will incapsulate checking of [State] type in [checkHandleable] and class
* casting in [handleState] * casting in [handleState]
*/ */
class StateHandlerHolder<I : State>( class StatesHandlerHolder<I : State>(
private val inputKlass: KClass<I>, private val inputKlass: KClass<I>,
private val strict: Boolean = false, private val strict: Boolean = false,
private val delegateTo: StatesHandler<I> private val delegateTo: StatesHandler<I>
@@ -19,9 +19,20 @@ class StateHandlerHolder<I : State>(
/** /**
* Calls [delegateTo] method [StatesHandler.handleState] with [state] casted to [I]. Use [checkHandleable] * Calls [delegateTo] method [StatesHandler.handleState] with [state] casted to [I]. Use [checkHandleable]
* to be sure that this [StateHandlerHolder] will be able to handle [state] * to be sure that this [StatesHandlerHolder] will be able to handle [state]
*/ */
override suspend fun StatesMachine.handleState(state: State): State? { override suspend fun StatesMachine.handleState(state: State): State? {
return delegateTo.run { handleState(state as I) } return delegateTo.run { handleState(state as I) }
} }
} }
@Deprecated("Renamed", ReplaceWith("StatesHandlerHolder"))
typealias StateHandlerHolder<T> = StatesHandlerHolder<T>
inline fun <reified T : State> StatesHandler<T>.holder(
strict: Boolean = true
) = StatesHandlerHolder(
T::class,
strict,
this
)

View File

@@ -2,11 +2,10 @@ package dev.inmo.micro_utils.fsm.common
import dev.inmo.micro_utils.coroutines.* import dev.inmo.micro_utils.coroutines.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.flow.asFlow
private suspend fun <I : State> StatesMachine.launchStateHandling( private suspend fun <I : State> StatesMachine.launchStateHandling(
state: State, state: State,
handlers: List<StateHandlerHolder<out I>> handlers: List<StatesHandlerHolder<out I>>
): State? { ): State? {
return handlers.firstOrNull { it.checkHandleable(state) } ?.run { return handlers.firstOrNull { it.checkHandleable(state) } ?.run {
handleState(state) handleState(state)
@@ -35,7 +34,7 @@ interface StatesMachine : StatesHandler<State> {
*/ */
operator fun invoke( operator fun invoke(
statesManager: StatesManager, statesManager: StatesManager,
handlers: List<StateHandlerHolder<*>> handlers: List<StatesHandlerHolder<*>>
) = DefaultStatesMachine(statesManager, handlers) ) = DefaultStatesMachine(statesManager, handlers)
} }
} }
@@ -46,7 +45,7 @@ interface StatesMachine : StatesHandler<State> {
*/ */
class DefaultStatesMachine ( class DefaultStatesMachine (
private val statesManager: StatesManager, private val statesManager: StatesManager,
private val handlers: List<StateHandlerHolder<*>> private val handlers: List<StatesHandlerHolder<*>>
) : StatesMachine { ) : StatesMachine {
/** /**
* Will call [launchStateHandling] for state handling * Will call [launchStateHandling] for state handling

View File

@@ -2,25 +2,27 @@ package dev.inmo.micro_utils.fsm.common.dsl
import dev.inmo.micro_utils.fsm.common.* import dev.inmo.micro_utils.fsm.common.*
import dev.inmo.micro_utils.fsm.common.managers.* import dev.inmo.micro_utils.fsm.common.managers.*
import dev.inmo.micro_utils.fsm.common.managers.InMemoryStatesManager
import kotlin.reflect.KClass import kotlin.reflect.KClass
class FSMBuilder( class FSMBuilder(
var statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()) var statesManager: StatesManager = DefaultStatesManager(InMemoryDefaultStatesManagerRepo()),
var defaultStateHandler: StatesHandler<State>? = StatesHandler { null }
) { ) {
private var states = mutableListOf<StateHandlerHolder<*>>() private var states = mutableListOf<StatesHandlerHolder<*>>()
fun <I : State> add(kClass: KClass<I>, handler: StatesHandler<I>) { fun <I : State> add(kClass: KClass<I>, handler: StatesHandler<I>) {
states.add(StateHandlerHolder(kClass, false, handler)) states.add(StatesHandlerHolder(kClass, false, handler))
} }
fun <I : State> addStrict(kClass: KClass<I>, handler: StatesHandler<I>) { fun <I : State> addStrict(kClass: KClass<I>, handler: StatesHandler<I>) {
states.add(StateHandlerHolder(kClass, true, handler)) states.add(StatesHandlerHolder(kClass, true, handler))
} }
fun build() = StatesMachine( fun build() = StatesMachine(
statesManager, statesManager,
states.toList() states.toList().let { list ->
defaultStateHandler ?.let { list + it.holder(false) } ?: list
}
) )
} }

View File

@@ -12,9 +12,9 @@ kotlin_coroutines_version=1.5.2
kotlin_serialisation_core_version=1.3.0 kotlin_serialisation_core_version=1.3.0
kotlin_exposed_version=0.35.3 kotlin_exposed_version=0.35.3
ktor_version=1.6.4 ktor_version=1.6.5
klockVersion=2.4.6 klockVersion=2.4.7
github_release_plugin_version=2.2.12 github_release_plugin_version=2.2.12
@@ -45,5 +45,5 @@ dokka_version=1.5.31
# Project data # Project data
group=dev.inmo group=dev.inmo
version=0.7.4 version=0.7.5
android_code_version=78 android_code_version=79

View File

@@ -1,3 +1,5 @@
@file:Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
package dev.inmo.micro_utils.language_codes package dev.inmo.micro_utils.language_codes
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@@ -1,3 +1,5 @@
@file:Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
package dev.inmo.micro_utils.mime_types package dev.inmo.micro_utils.mime_types
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable