From c02f18d5defcb0e67426eb25396196564a6cf902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Lamarque?= Date: Wed, 21 Feb 2024 19:17:28 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20StrictlyNegativeInt.Companion?= =?UTF-8?q?.createOrNull(Number)=20(#347)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/types.api | 1 + .../types/number/StrictlyNegativeInt.kt | 26 ++++++++++++++ .../types/number/StrictlyNegativeIntTest.kt | 35 +++++++++++++++++-- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/api/types.api b/src/api/types.api index b884f38a6..31ec1f866 100644 --- a/src/api/types.api +++ b/src/api/types.api @@ -350,6 +350,7 @@ public final class kotools/types/number/StrictlyNegativeInt : kotools/types/numb } public final class kotools/types/number/StrictlyNegativeInt$Companion { + public final synthetic fun createOrNull-1FaSkl4 (Ljava/lang/Number;)Lkotools/types/number/StrictlyNegativeInt; public final fun getMax-r6XGqFM ()I public final fun getMin-r6XGqFM ()I public final fun random-r6XGqFM ()I diff --git a/src/commonMain/kotlin/kotools/types/number/StrictlyNegativeInt.kt b/src/commonMain/kotlin/kotools/types/number/StrictlyNegativeInt.kt index 224883faf..ce2ca76d6 100644 --- a/src/commonMain/kotlin/kotools/types/number/StrictlyNegativeInt.kt +++ b/src/commonMain/kotlin/kotools/types/number/StrictlyNegativeInt.kt @@ -7,6 +7,8 @@ import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder +import kotools.types.experimental.ExperimentalKotoolsTypesApi +import kotools.types.internal.ExperimentalSince import kotools.types.internal.InternalKotoolsTypesApi import kotools.types.internal.KotoolsTypesPackage import kotools.types.internal.KotoolsTypesVersion @@ -54,6 +56,30 @@ public value class StrictlyNegativeInt private constructor( (-1).toStrictlyNegativeInt()::getOrThrow ) + /** + * Creates a [StrictlyNegativeInt] from the specified [number], or + * returns `null` if the [number] is greater than or equals zero. + * + * Here's an example of calling this function from Kotlin code: + * + * ```kotlin + * val number: StrictlyNegativeInt? = + * StrictlyNegativeInt.createOrNull(-7) + * println(number) // -7 + * ``` + * + * The [StrictlyNegativeInt] type being an + * [inline value class](https://kotlinlang.org/docs/inline-classes.html), + * this function is not available yet for Java users. + */ + @ExperimentalKotoolsTypesApi + @ExperimentalSince(KotoolsTypesVersion.Unreleased) + @JvmSynthetic + public fun createOrNull(number: Number): StrictlyNegativeInt? = number + .toInt() + .takeIf(Int::isStrictlyNegative) + ?.let(::StrictlyNegativeInt) + @InternalKotoolsTypesApi @JvmSynthetic internal infix fun orFail(value: Int): StrictlyNegativeInt { diff --git a/src/commonTest/kotlin/kotools/types/number/StrictlyNegativeIntTest.kt b/src/commonTest/kotlin/kotools/types/number/StrictlyNegativeIntTest.kt index 588bdd17b..63bd9db3b 100644 --- a/src/commonTest/kotlin/kotools/types/number/StrictlyNegativeIntTest.kt +++ b/src/commonTest/kotlin/kotools/types/number/StrictlyNegativeIntTest.kt @@ -1,5 +1,3 @@ -@file:OptIn(InternalKotoolsTypesApi::class) - package kotools.types.number import kotlinx.serialization.ExperimentalSerializationApi @@ -11,6 +9,7 @@ import kotlinx.serialization.descriptors.SerialKind import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import kotlinx.serialization.serializer +import kotools.types.experimental.ExperimentalKotoolsTypesApi import kotools.types.internal.ErrorMessage import kotools.types.internal.InternalKotoolsTypesApi import kotools.types.internal.KotoolsTypesPackage @@ -18,9 +17,12 @@ import kotools.types.internal.shouldBeStrictlyNegative import kotools.types.internal.simpleNameOf import kotools.types.shouldEqual import kotools.types.shouldNotEqual +import kotlin.random.Random import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith +import kotlin.test.assertNotNull +import kotlin.test.assertNull class StrictlyNegativeIntCompanionTest { @Test @@ -35,6 +37,32 @@ class StrictlyNegativeIntCompanionTest { result.toInt() shouldEqual -1 } + @OptIn(ExperimentalKotoolsTypesApi::class) + @Test + fun createOrNull_should_pass_with_a_Number_that_is_less_than_zero() { + val number: Number = Random.nextInt(from = Int.MIN_VALUE, until = 0) + val actual: StrictlyNegativeInt? = + StrictlyNegativeInt.createOrNull(number) + assertNotNull(actual) + } + + @OptIn(ExperimentalKotoolsTypesApi::class) + @Test + fun createOrNull_should_fail_with_a_Number_that_equals_zero() { + val actual: StrictlyNegativeInt? = + StrictlyNegativeInt.createOrNull(0) + assertNull(actual) + } + + @OptIn(ExperimentalKotoolsTypesApi::class) + @Test + fun createOrNull_should_fail_with_a_Number_that_is_greater_than_zero() { + val number: Number = Random.nextInt(from = 1, until = Int.MAX_VALUE) + val actual: StrictlyNegativeInt? = + StrictlyNegativeInt.createOrNull(number) + assertNull(actual) + } + @Test fun random_should_return_different_values() { val result: StrictlyNegativeInt = StrictlyNegativeInt.random() @@ -50,6 +78,7 @@ class StrictlyNegativeIntTest { result.getOrThrow().toInt() shouldEqual value } + @OptIn(InternalKotoolsTypesApi::class) @Test fun number_toStrictlyNegativeInt_should_fail_with_a_positive_Int() { val number: Number = PositiveInt.random() @@ -71,6 +100,7 @@ class StrictlyNegativeIntTest { class StrictlyNegativeIntSerializerTest { @ExperimentalSerializationApi + @OptIn(InternalKotoolsTypesApi::class) @Test fun descriptor_serial_name_should_be_the_qualified_name_of_StrictlyNegativeInt() { val actual: String = serializer() @@ -109,6 +139,7 @@ class StrictlyNegativeIntSerializerTest { assertEquals(expected, actual) } + @OptIn(InternalKotoolsTypesApi::class) @Test fun deserialization_should_fail_with_a_positive_Int() { val value: Int = PositiveInt.random()