mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2025-09-17 14:29:24 +00:00
Compare commits
37 Commits
Author | SHA1 | Date | |
---|---|---|---|
44e26ccb4f | |||
2a783f6e2b | |||
6058d6a724 | |||
2e9c7eb5fa | |||
e75465ad10 | |||
de01ad54e9 | |||
eeea7ddbe3 | |||
e0b18bec05 | |||
410e89bba9 | |||
9ef19dc42b | |||
0337d1b82d | |||
f5bd4c5ccb | |||
630f9bc0d4 | |||
18b4ffece1 | |||
f64e1effa3 | |||
847fcbb488 | |||
88002ec8e7 | |||
7f8db6a29d | |||
b183b82443 | |||
5dad27de72 | |||
6b66084d0e | |||
50b56a7c39 | |||
7ab7d14471 | |||
bdcc179b7b | |||
55ffd4b46f | |||
7fc5ee70e1 | |||
a24a335743 | |||
ef9af71960 | |||
925702d315 | |||
d50dffec8c | |||
cef2081a13 | |||
06c8bde7c9 | |||
c9bbfa3820 | |||
eed7cfdc42 | |||
bd9b0d16ab | |||
ea6c33b497 | |||
dc80ade2fb |
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@@ -1,12 +0,0 @@
|
||||
name: Regular build
|
||||
on: [push]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Build
|
||||
run: ./gradlew build
|
3
.github/workflows/dokka_push.yml
vendored
3
.github/workflows/dokka_push.yml
vendored
@@ -11,6 +11,9 @@ jobs:
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Fix android 31.0.0 dx
|
||||
continue-on-error: true
|
||||
run: cd /usr/local/lib/android/sdk/build-tools/31.0.0/ && mv d8 dx && cd lib && mv d8.jar dx.jar
|
||||
- name: Build
|
||||
run: ./gradlew dokkaHtml
|
||||
- name: Publish KDocs
|
||||
|
4
.github/workflows/packages_push.yml
vendored
4
.github/workflows/packages_push.yml
vendored
@@ -9,6 +9,9 @@ jobs:
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Fix android 31.0.0 dx
|
||||
continue-on-error: true
|
||||
run: cd /usr/local/lib/android/sdk/build-tools/31.0.0/ && mv d8 dx && cd lib && mv d8.jar dx.jar
|
||||
- name: Rewrite version
|
||||
run: |
|
||||
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"
|
||||
@@ -18,6 +21,7 @@ jobs:
|
||||
- name: Build
|
||||
run: ./gradlew build
|
||||
- name: Publish
|
||||
continue-on-error: true
|
||||
run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication -x signAndroidDebugPublication -x signAndroidReleasePublication -x signKotlinMultiplatformPublication
|
||||
env:
|
||||
GITHUBPACKAGES_USER: ${{ github.actor }}
|
||||
|
59
CHANGELOG.md
59
CHANGELOG.md
@@ -1,5 +1,64 @@
|
||||
# Changelog
|
||||
|
||||
## 0.6.0
|
||||
|
||||
**THIS VERSION HAS MIGRATED FROM KORLIBS KLOCK TO KOTLINX DATETIME. CAREFUL**
|
||||
|
||||
* `Versions`
|
||||
* `Klock` -> `kotlinx.datetime`
|
||||
|
||||
## 0.5.31
|
||||
|
||||
* `Versions`:
|
||||
* `Klock`: `2.4.2` -> `2.4.3`
|
||||
* `Ktor`: `1.6.3` -> `1.6.4`
|
||||
|
||||
## 0.5.30
|
||||
|
||||
* `Versions`:
|
||||
* `Serialization`: `1.2.2` -> `1.3.0`
|
||||
|
||||
## 0.5.29
|
||||
|
||||
* `Versions`:
|
||||
* `Exposed`: `0.34.2` -> `0.35.1`
|
||||
|
||||
## 0.5.28
|
||||
|
||||
* `Versions`:
|
||||
* `Kotlin`: `1.5.30` -> `1.5.31`
|
||||
* `Klock`: `2.4.1` -> `2.4.2`
|
||||
|
||||
## 0.5.27
|
||||
|
||||
* `Versions`:
|
||||
* `Exposed`: `0.34.1` -> `0.34.2`
|
||||
|
||||
## 0.5.26
|
||||
|
||||
* `Repos`:
|
||||
* `InMemory`:
|
||||
* `MapCRUDRepo`s and `MapKeyValueRepo`s got `protected` methods and properties instead of private
|
||||
|
||||
## 0.5.25
|
||||
|
||||
* `Versions`:
|
||||
* `UUID`: `0.3.0` -> `0.3.1`
|
||||
* `Common`:
|
||||
* New property `MPPFile#withoutSlashAtTheEnd`
|
||||
* Extension `clamp` has been deprecated
|
||||
* New extension `Iterable#diff`
|
||||
* `Serialization`:
|
||||
* New operators `TypedSerializer#plusAssign` and `TypedSerializer#minusAssign`
|
||||
|
||||
## 0.5.24
|
||||
|
||||
* `Versions`:
|
||||
* `Coroutines`: `1.5.1` -> `1.5.2`
|
||||
* `Klock`: `2.3.4` -> `2.4.1`
|
||||
* `Coroutines`:
|
||||
* New function `CoroutineScope` with safely exceptions handler as second parameter
|
||||
|
||||
## 0.5.23
|
||||
|
||||
* `Versions`:
|
||||
|
@@ -1,10 +1,5 @@
|
||||
package dev.inmo.micro_utils.common
|
||||
|
||||
@Deprecated("Redundant", ReplaceWith("coerceIn(min, max)"))
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun <T : Comparable<T>> T.clamp(min: T, max: T): T {
|
||||
return when {
|
||||
this < min -> min
|
||||
this > max -> max
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
inline fun <T : Comparable<T>> T.clamp(min: T, max: T): T = coerceIn(min, max)
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
package dev.inmo.micro_utils.common
|
||||
|
||||
import kotlin.jvm.JvmInline
|
||||
|
||||
private inline fun <T> getObject(
|
||||
additional: MutableList<T>,
|
||||
iterator: Iterator<T>
|
||||
@@ -27,8 +29,8 @@ data class Diff<T> internal constructor(
|
||||
|
||||
private inline fun <T> performChanges(
|
||||
potentialChanges: MutableList<Pair<IndexedValue<T>?, IndexedValue<T>?>>,
|
||||
additionalsInOld: MutableList<T>,
|
||||
additionalsInNew: MutableList<T>,
|
||||
additionsInOld: MutableList<T>,
|
||||
additionsInNew: MutableList<T>,
|
||||
changedList: MutableList<Pair<IndexedValue<T>, IndexedValue<T>>>,
|
||||
removedList: MutableList<IndexedValue<T>>,
|
||||
addedList: MutableList<IndexedValue<T>>,
|
||||
@@ -52,20 +54,20 @@ private inline fun <T> performChanges(
|
||||
newPotentials.first().second ?.let { addedList.add(it) }
|
||||
newPotentials.drop(1).take(newPotentials.size - 2).forEach { (oldOne, newOne) ->
|
||||
addedList.add(newOne!!)
|
||||
oldOne ?.let { additionalsInOld.add(oldOne.value) }
|
||||
oldOne ?.let { additionsInOld.add(oldOne.value) }
|
||||
}
|
||||
if (newPotentials.size > 1) {
|
||||
newPotentials.last().first ?.value ?.let { additionalsInOld.add(it) }
|
||||
newPotentials.last().first ?.value ?.let { additionsInOld.add(it) }
|
||||
}
|
||||
}
|
||||
newOneEqualToOldObject -> {
|
||||
newPotentials.first().first ?.let { removedList.add(it) }
|
||||
newPotentials.drop(1).take(newPotentials.size - 2).forEach { (oldOne, newOne) ->
|
||||
removedList.add(oldOne!!)
|
||||
newOne ?.let { additionalsInNew.add(newOne.value) }
|
||||
newOne ?.let { additionsInNew.add(newOne.value) }
|
||||
}
|
||||
if (newPotentials.size > 1) {
|
||||
newPotentials.last().second ?.value ?.let { additionalsInNew.add(it) }
|
||||
newPotentials.last().second ?.value ?.let { additionsInNew.add(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,6 +141,10 @@ fun <T> Iterable<T>.calculateDiff(
|
||||
|
||||
return Diff(removedObjects.toList(), changedObjects.toList(), addedObjects.toList())
|
||||
}
|
||||
inline fun <T> Iterable<T>.diff(
|
||||
other: Iterable<T>,
|
||||
strictComparison: Boolean = false
|
||||
): Diff<T> = calculateDiff(other, strictComparison)
|
||||
|
||||
inline fun <T> Diff(old: Iterable<T>, new: Iterable<T>) = old.calculateDiff(new)
|
||||
inline fun <T> StrictDiff(old: Iterable<T>, new: Iterable<T>) = old.calculateDiff(new, true)
|
||||
|
@@ -7,7 +7,7 @@ import kotlin.jvm.JvmInline
|
||||
@JvmInline
|
||||
value class FileName(val string: String) {
|
||||
val name: String
|
||||
get() = string.takeLastWhile { it != '/' }
|
||||
get() = withoutSlashAtTheEnd.takeLastWhile { it != '/' }
|
||||
val extension: String
|
||||
get() = name.takeLastWhile { it != '.' }
|
||||
val nameWithoutExtension: String
|
||||
@@ -17,6 +17,8 @@ value class FileName(val string: String) {
|
||||
filename.substring(0, it)
|
||||
} ?: filename
|
||||
}
|
||||
val withoutSlashAtTheEnd: String
|
||||
get() = string.dropLastWhile { it == '/' }
|
||||
override fun toString(): String = string
|
||||
}
|
||||
|
||||
|
@@ -147,3 +147,10 @@ suspend inline fun <T> runCatchingSafelyWithoutExceptions(
|
||||
): Result<T?> = runCatching {
|
||||
safelyWithoutExceptions(onException, block)
|
||||
}
|
||||
|
||||
inline fun CoroutineScope(
|
||||
context: CoroutineContext,
|
||||
noinline defaultExceptionsHandler: ExceptionHandler<Unit>
|
||||
) = CoroutineScope(
|
||||
context + ContextSafelyExceptionHandler(defaultExceptionsHandler)
|
||||
)
|
||||
|
@@ -7,18 +7,18 @@ android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
org.gradle.jvmargs=-Xmx2g
|
||||
|
||||
kotlin_version=1.5.30
|
||||
kotlin_coroutines_version=1.5.1
|
||||
kotlin_serialisation_core_version=1.2.2
|
||||
kotlin_exposed_version=0.34.1
|
||||
kotlin_version=1.5.31
|
||||
kotlin_coroutines_version=1.5.2
|
||||
kotlin_serialisation_core_version=1.3.0
|
||||
kotlin_exposed_version=0.35.1
|
||||
|
||||
ktor_version=1.6.3
|
||||
ktor_version=1.6.4
|
||||
|
||||
klockVersion=2.3.4
|
||||
datetime_version=0.3.0
|
||||
|
||||
github_release_plugin_version=2.2.12
|
||||
|
||||
uuidVersion=0.3.0
|
||||
uuidVersion=0.3.1
|
||||
|
||||
# ANDROID
|
||||
|
||||
@@ -27,8 +27,8 @@ androidx_recycler_version=1.2.1
|
||||
appcompat_version=1.3.1
|
||||
|
||||
android_minSdkVersion=19
|
||||
android_compileSdkVersion=30
|
||||
android_buildToolsVersion=30.0.3
|
||||
android_compileSdkVersion=31
|
||||
android_buildToolsVersion=31.0.0
|
||||
dexcount_version=3.0.0
|
||||
junit_version=4.12
|
||||
test_ext_junit_version=1.1.2
|
||||
@@ -40,10 +40,10 @@ crypto_js_version=4.1.1
|
||||
|
||||
# Dokka
|
||||
|
||||
dokka_version=1.5.0
|
||||
dokka_version=1.5.30
|
||||
|
||||
# Project data
|
||||
|
||||
group=dev.inmo
|
||||
version=0.5.23
|
||||
android_code_version=64
|
||||
version=0.6.0
|
||||
android_code_version=73
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@@ -11,7 +11,7 @@ kotlin {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api "org.jetbrains.kotlinx:kotlinx-serialization-cbor:$kotlin_serialisation_core_version"
|
||||
api "com.soywiz.korlibs.klock:klock:$klockVersion"
|
||||
api "org.jetbrains.kotlinx:kotlinx-datetime:$datetime_version"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,17 +1,17 @@
|
||||
package dev.inmo.micro_utils.ktor.common
|
||||
|
||||
import com.soywiz.klock.DateTime
|
||||
import kotlinx.datetime.Instant
|
||||
|
||||
typealias FromToDateTime = Pair<DateTime?, DateTime?>
|
||||
typealias FromToDateTime = Pair<Instant?, Instant?>
|
||||
|
||||
val FromToDateTime.asFromToUrlPart: QueryParams
|
||||
get() = mapOf(
|
||||
"from" to first ?.unixMillis ?.toString(),
|
||||
"to" to second ?.unixMillis ?.toString()
|
||||
"from" to first ?.toEpochMilliseconds() ?.toString(),
|
||||
"to" to second ?.toEpochMilliseconds() ?.toString()
|
||||
)
|
||||
|
||||
val QueryParams.extractFromToDateTime: FromToDateTime
|
||||
get() = FromToDateTime(
|
||||
get("from") ?.toDoubleOrNull() ?.let { DateTime(it) },
|
||||
get("to") ?.toDoubleOrNull() ?.let { DateTime(it) }
|
||||
get("from") ?.run { toLongOrNull() ?: (toDoubleOrNull() ?.toLong()) } ?.let { Instant.fromEpochMilliseconds(it) },
|
||||
get("to") ?.run { toLongOrNull() ?: (toDoubleOrNull() ?.toLong()) } ?.let { Instant.fromEpochMilliseconds(it) }
|
||||
)
|
||||
|
@@ -1,11 +1,11 @@
|
||||
package dev.inmo.micro_utils.ktor.server
|
||||
|
||||
import com.soywiz.klock.DateTime
|
||||
import dev.inmo.micro_utils.ktor.common.FromToDateTime
|
||||
import io.ktor.http.Parameters
|
||||
import kotlinx.datetime.Instant
|
||||
|
||||
val Parameters.extractFromToDateTime: FromToDateTime
|
||||
get() = FromToDateTime(
|
||||
get("from") ?.toDoubleOrNull() ?.let { DateTime(it) },
|
||||
get("to") ?.toDoubleOrNull() ?.let { DateTime(it) }
|
||||
get("from") ?.run { toLongOrNull() ?: (toDoubleOrNull() ?.toLong()) } ?.let { Instant.fromEpochMilliseconds(it) },
|
||||
get("to") ?.run { toLongOrNull() ?: (toDoubleOrNull() ?.toLong()) } ?.let { Instant.fromEpochMilliseconds(it) }
|
||||
)
|
||||
|
@@ -24,3 +24,9 @@ kotlin {
|
||||
}
|
||||
|
||||
apply from: "$defaultAndroidSettingsPresetPath"
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(8)
|
||||
}
|
||||
}
|
||||
|
@@ -26,3 +26,9 @@ kotlin {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(8)
|
||||
}
|
||||
}
|
||||
|
@@ -48,3 +48,9 @@ kotlin {
|
||||
}
|
||||
|
||||
apply from: "$defaultAndroidSettingsPresetPath"
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(8)
|
||||
}
|
||||
}
|
||||
|
@@ -23,13 +23,13 @@ class ReadMapCRUDRepo<ObjectType, IdType>(
|
||||
}
|
||||
|
||||
abstract class WriteMapCRUDRepo<ObjectType, IdType, InputValueType>(
|
||||
private val map: MutableMap<IdType, ObjectType> = mutableMapOf()
|
||||
protected val map: MutableMap<IdType, ObjectType> = mutableMapOf()
|
||||
) : WriteStandardCRUDRepo<ObjectType, IdType, InputValueType> {
|
||||
private val _newObjectsFlow: MutableSharedFlow<ObjectType> = MutableSharedFlow()
|
||||
protected val _newObjectsFlow: MutableSharedFlow<ObjectType> = MutableSharedFlow()
|
||||
override val newObjectsFlow: Flow<ObjectType> = _newObjectsFlow.asSharedFlow()
|
||||
private val _updatedObjectsFlow: MutableSharedFlow<ObjectType> = MutableSharedFlow()
|
||||
protected val _updatedObjectsFlow: MutableSharedFlow<ObjectType> = MutableSharedFlow()
|
||||
override val updatedObjectsFlow: Flow<ObjectType> = _updatedObjectsFlow.asSharedFlow()
|
||||
private val _deletedObjectsIdsFlow: MutableSharedFlow<IdType> = MutableSharedFlow()
|
||||
protected val _deletedObjectsIdsFlow: MutableSharedFlow<IdType> = MutableSharedFlow()
|
||||
override val deletedObjectsIdsFlow: Flow<IdType> = _deletedObjectsIdsFlow.asSharedFlow()
|
||||
|
||||
protected abstract suspend fun updateObject(newValue: InputValueType, id: IdType, old: ObjectType): ObjectType
|
||||
|
@@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
|
||||
class ReadMapKeyValueRepo<Key, Value>(
|
||||
private val map: Map<Key, Value> = emptyMap()
|
||||
protected val map: Map<Key, Value> = emptyMap()
|
||||
) : ReadStandardKeyValueRepo<Key, Value> {
|
||||
override suspend fun get(k: Key): Value? = map[k]
|
||||
|
||||
|
@@ -11,6 +11,7 @@ open class TypedSerializer<T : Any>(
|
||||
presetSerializers: Map<String, KSerializer<out T>> = emptyMap(),
|
||||
) : KSerializer<T> {
|
||||
protected val serializers = presetSerializers.toMutableMap()
|
||||
@ExperimentalSerializationApi
|
||||
@InternalSerializationApi
|
||||
override val descriptor: SerialDescriptor = buildSerialDescriptor(
|
||||
"TypedSerializer",
|
||||
@@ -32,8 +33,9 @@ open class TypedSerializer<T : Any>(
|
||||
element("value", ContextualSerializer(kClass).descriptor)
|
||||
}
|
||||
|
||||
@ExperimentalSerializationApi
|
||||
@InternalSerializationApi
|
||||
open override fun deserialize(decoder: Decoder): T {
|
||||
override fun deserialize(decoder: Decoder): T {
|
||||
return decoder.decodeStructure(descriptor) {
|
||||
var type: String? = null
|
||||
lateinit var result: T
|
||||
@@ -56,13 +58,15 @@ open class TypedSerializer<T : Any>(
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalSerializationApi
|
||||
@InternalSerializationApi
|
||||
protected open fun <O: T> CompositeEncoder.encode(value: O) {
|
||||
encodeSerializableElement(descriptor, 1, value::class.serializer() as KSerializer<O>, value)
|
||||
}
|
||||
|
||||
@ExperimentalSerializationApi
|
||||
@InternalSerializationApi
|
||||
open override fun serialize(encoder: Encoder, value: T) {
|
||||
override fun serialize(encoder: Encoder, value: T) {
|
||||
encoder.encodeStructure(descriptor) {
|
||||
val valueSerializer = value::class.serializer()
|
||||
val type = serializers.keys.first { serializers[it] == valueSerializer }
|
||||
@@ -81,6 +85,16 @@ open class TypedSerializer<T : Any>(
|
||||
}
|
||||
}
|
||||
|
||||
@InternalSerializationApi
|
||||
operator fun <T : Any> TypedSerializer<T>.plusAssign(kClass: KClass<T>) {
|
||||
include(kClass.simpleName!!, kClass.serializer())
|
||||
}
|
||||
|
||||
@InternalSerializationApi
|
||||
operator fun <T : Any> TypedSerializer<T>.minusAssign(kClass: KClass<T>) {
|
||||
exclude(kClass.simpleName!!)
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> TypedSerializer(
|
||||
presetSerializers: Map<String, KSerializer<out T>> = emptyMap()
|
||||
) = TypedSerializer(T::class, presetSerializers)
|
||||
|
Reference in New Issue
Block a user