diff --git a/CHANGELOG.md b/CHANGELOG.md index 87362ac78ab..5daa01e3045 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.11.7 + +* `Common`: + * New abstractions `SimpleMapper` and `SimpleSuspendableMapper` +* `Repos`: + * `Common`: + * Add mappers for `CRUDRepo` + ## 0.11.6 * `FSM`: diff --git a/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Mapper.kt b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Mapper.kt new file mode 100644 index 00000000000..3494ebfff1b --- /dev/null +++ b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/Mapper.kt @@ -0,0 +1,53 @@ +package dev.inmo.micro_utils.common + +import kotlin.jvm.JvmName + +interface SimpleMapper { + fun convertToT1(from: T2): T1 + fun convertToT2(from: T1): T2 +} + +@JvmName("convertFromT2") +fun SimpleMapper.convert(from: T2) = convertToT1(from) +@JvmName("convertFromT1") +fun SimpleMapper.convert(from: T1) = convertToT2(from) + +class SimpleMapperImpl( + private val t1: (T2) -> T1, + private val t2: (T1) -> T2, +) : SimpleMapper { + override fun convertToT1(from: T2): T1 = t1.invoke(from) + + override fun convertToT2(from: T1): T2 = t2.invoke(from) +} + +@Suppress("NOTHING_TO_INLINE") +inline fun simpleMapper( + noinline t1: (T2) -> T1, + noinline t2: (T1) -> T2, +) = SimpleMapperImpl(t1, t2) + +interface SimpleSuspendableMapper { + suspend fun convertToT1(from: T2): T1 + suspend fun convertToT2(from: T1): T2 +} + +@JvmName("convertFromT2") +suspend fun SimpleSuspendableMapper.convert(from: T2) = convertToT1(from) +@JvmName("convertFromT1") +suspend fun SimpleSuspendableMapper.convert(from: T1) = convertToT2(from) + +class SimpleSuspendableMapperImpl( + private val t1: suspend (T2) -> T1, + private val t2: suspend (T1) -> T2, +) : SimpleSuspendableMapper { + override suspend fun convertToT1(from: T2): T1 = t1.invoke(from) + + override suspend fun convertToT2(from: T1): T2 = t2.invoke(from) +} + +@Suppress("NOTHING_TO_INLINE") +inline fun simpleSuspendableMapper( + noinline t1: suspend (T2) -> T1, + noinline t2: suspend (T1) -> T2, +) = SimpleSuspendableMapperImpl(t1, t2) diff --git a/gradle.properties b/gradle.properties index 835cff3d3c3..d4794a30290 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,5 +14,5 @@ crypto_js_version=4.1.1 # Project data group=dev.inmo -version=0.11.6 -android_code_version=130 +version=0.11.7 +android_code_version=131 diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapperRepo.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapperRepo.kt index 313c7970f60..3fdf345e073 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapperRepo.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/MapperRepo.kt @@ -1,22 +1,51 @@ package dev.inmo.micro_utils.repos +import dev.inmo.micro_utils.common.* + @Suppress("UNCHECKED_CAST") interface MapperRepo { + val keyMapper: SimpleSuspendableMapper + get() = simpleSuspendableMapper( + { it.toInnerKey() }, + { it.toOutKey() } + ) + val valueMapper: SimpleSuspendableMapper + get() = simpleSuspendableMapper( + { it.toInnerValue() }, + { it.toOutValue() } + ) + suspend fun FromKey.toOutKey() = this as ToKey suspend fun FromValue.toOutValue() = this as ToValue suspend fun ToKey.toInnerKey() = this as FromKey suspend fun ToValue.toInnerValue() = this as FromValue + + companion object } -inline fun mapper( - crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, - crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, - crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, - crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, -) = object : MapperRepo { +class SimpleMapperRepo( + private val keyFromToTo: suspend FromKey.() -> ToKey, + private val valueFromToTo: suspend FromValue.() -> ToValue, + private val keyToToFrom: suspend ToKey.() -> FromKey, + private val valueToToFrom: suspend ToValue.() -> FromValue +) : MapperRepo { override suspend fun FromKey.toOutKey(): ToKey = keyFromToTo() override suspend fun FromValue.toOutValue(): ToValue = valueFromToTo() override suspend fun ToKey.toInnerKey(): FromKey = keyToToFrom() override suspend fun ToValue.toInnerValue(): FromValue = valueToToFrom() } + +operator fun MapperRepo.Companion.invoke( + keyFromToTo: suspend FromKey.() -> ToKey, + valueFromToTo: suspend FromValue.() -> ToValue, + keyToToFrom: suspend ToKey.() -> FromKey, + valueToToFrom: suspend ToValue.() -> FromValue +) = SimpleMapperRepo(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) + +inline fun mapper( + noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, + noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, + noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, + noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, +) = MapperRepo(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/CRUDMappers.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/CRUDMappers.kt new file mode 100644 index 00000000000..97894431d7b --- /dev/null +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/CRUDMappers.kt @@ -0,0 +1,130 @@ +package dev.inmo.micro_utils.repos.mappers + +import dev.inmo.micro_utils.common.* +import dev.inmo.micro_utils.pagination.* +import dev.inmo.micro_utils.repos.* +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +open class MapperReadCRUDRepo( + private val to: ReadCRUDRepo, + mapper: MapperRepo +) : ReadCRUDRepo, MapperRepo by mapper { + override suspend fun getByPagination( + pagination: Pagination + ): PaginationResult = to.getByPagination( + pagination + ).let { + it.changeResultsUnchecked( + it.results.map { it.toInnerValue() } + ) + } + + override suspend fun count(): Long = to.count() + + override suspend fun contains(id: FromId): Boolean = to.contains(id.toOutKey()) + + override suspend fun getById(id: FromId): FromRegistered? = to.getById( + id.toOutKey() + ) ?.toInnerValue() +} + +@Suppress("NOTHING_TO_INLINE") +inline fun ReadCRUDRepo.withMapper( + mapper: MapperRepo +): ReadCRUDRepo = MapperReadCRUDRepo(this, mapper) + +@Suppress("NOTHING_TO_INLINE") +inline fun ReadCRUDRepo.withMapper( + noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, + noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, + noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, + noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, +): ReadCRUDRepo = withMapper( + mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) +) + +open class MapperWriteCRUDRepo( + private val to: WriteCRUDRepo, + mapper: MapperRepo, + inputMapper: SimpleSuspendableMapper +) : WriteCRUDRepo, + MapperRepo by mapper, + SimpleSuspendableMapper by inputMapper { + override val newObjectsFlow: Flow = to.newObjectsFlow.map { it.toInnerValue() } + override val updatedObjectsFlow: Flow = to.updatedObjectsFlow.map { it.toInnerValue() } + override val deletedObjectsIdsFlow: Flow = to.deletedObjectsIdsFlow.map { it.toInnerKey() } + + override suspend fun deleteById(ids: List) = to.deleteById(ids.map { it.toOutKey() }) + + override suspend fun update( + values: List> + ): List = to.update( + values.map { + it.first.toOutKey() to convert(it.second) + } + ).map { it.toInnerValue() } + + override suspend fun update( + id: FromId, + value: FromInput + ): FromRegistered? = to.update(id.toOutKey(), convert(value)) ?.toInnerValue() + + override suspend fun create(values: List): List = to.create( + values.map { + convert(it) + } + ).map { + it.toInnerValue() + } + +} + +@Suppress("NOTHING_TO_INLINE") +inline fun WriteCRUDRepo.withMapper( + mapper: MapperRepo, + simpleSuspendableMapper: SimpleSuspendableMapper +): WriteCRUDRepo = MapperWriteCRUDRepo(this, mapper, simpleSuspendableMapper) + +@Suppress("NOTHING_TO_INLINE") +inline fun WriteCRUDRepo.withMapper( + noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, + noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, + noinline inputFromToTo: suspend FromInput.() -> ToInput = { this as ToInput }, + noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, + noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, + noinline inputToToFrom: suspend ToInput.() -> FromInput = { this as FromInput }, +): WriteCRUDRepo = withMapper( + mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom), + simpleSuspendableMapper({ inputToToFrom(it) }, { inputFromToTo(it) }) +) + +@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") +open class MapperCRUDRepo( + private val to: CRUDRepo, + private val mapper: MapperRepo, + private val inputMapper: SimpleSuspendableMapper +) : CRUDRepo, + MapperRepo by mapper, + ReadCRUDRepo by MapperReadCRUDRepo(to, mapper), + WriteCRUDRepo by MapperWriteCRUDRepo(to, mapper, inputMapper) + + +@Suppress("NOTHING_TO_INLINE") +inline fun CRUDRepo.withMapper( + mapper: MapperRepo, + simpleSuspendableMapper: SimpleSuspendableMapper +): CRUDRepo = MapperCRUDRepo(this, mapper, simpleSuspendableMapper) + +@Suppress("NOTHING_TO_INLINE") +inline fun CRUDRepo.withMapper( + noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, + noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, + noinline inputFromToTo: suspend FromInput.() -> ToInput = { this as ToInput }, + noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, + noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, + noinline inputToToFrom: suspend ToInput.() -> FromInput = { this as FromInput }, +): CRUDRepo = withMapper( + mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom), + simpleSuspendableMapper({ inputToToFrom(it) }, { inputFromToTo(it) }) +) diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt index 23955920fe8..4df2b614f6e 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/KeyValueMappers.kt @@ -77,10 +77,10 @@ inline fun ReadKeyValueRepo @Suppress("NOTHING_TO_INLINE") inline fun ReadKeyValueRepo.withMapper( - crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, - crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, - crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, - crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, + noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, + noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, + noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, + noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, ): ReadKeyValueRepo = withMapper( mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) ) @@ -122,10 +122,10 @@ inline fun WriteKeyValueRepo WriteKeyValueRepo.withMapper( - crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, - crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, - crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, - crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, + noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, + noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, + noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, + noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, ): WriteKeyValueRepo = withMapper( mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) ) @@ -148,10 +148,10 @@ inline fun KeyValueRepo.wit @Suppress("NOTHING_TO_INLINE") inline fun KeyValueRepo.withMapper( - crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, - crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, - crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, - crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, + noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, + noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, + noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, + noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, ): KeyValueRepo = withMapper( mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) ) diff --git a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt index 5e5d5b44d5f..f74b81d9149 100644 --- a/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt +++ b/repos/common/src/commonMain/kotlin/dev/inmo/micro_utils/repos/mappers/OneToManyKeyValueMappers.kt @@ -75,10 +75,10 @@ inline fun ReadKeyValuesRepo ReadKeyValuesRepo.withMapper( - crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, - crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, - crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, - crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, + noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, + noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, + noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, + noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, ): ReadKeyValuesRepo = withMapper( mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) ) @@ -128,10 +128,10 @@ inline fun WriteKeyValuesRepo WriteKeyValuesRepo.withMapper( - crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, - crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, - crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, - crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, + noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, + noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, + noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, + noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, ): WriteKeyValuesRepo = withMapper( mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) ) @@ -154,10 +154,10 @@ inline fun KeyValuesRepo.wi @Suppress("NOTHING_TO_INLINE") inline fun KeyValuesRepo.withMapper( - crossinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, - crossinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, - crossinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, - crossinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, + noinline keyFromToTo: suspend FromKey.() -> ToKey = { this as ToKey }, + noinline valueFromToTo: suspend FromValue.() -> ToValue = { this as ToValue }, + noinline keyToToFrom: suspend ToKey.() -> FromKey = { this as FromKey }, + noinline valueToToFrom: suspend ToValue.() -> FromValue = { this as FromValue }, ): KeyValuesRepo = withMapper( mapper(keyFromToTo, valueFromToTo, keyToToFrom, valueToToFrom) )