From 37ee3bf9523ba9ba040c1db745c6058a920541da Mon Sep 17 00:00:00 2001 From: Kazik Pogoda Date: Thu, 5 Dec 2024 20:12:20 +0100 Subject: [PATCH] Add JVM and nonJVM Money implementation --- src/jvmMain/kotlin/JvmMoney.kt | 100 +++++++++++++++++++++++++++ src/nonJvmMain/kotlin/NonJvmMoney.kt | 97 ++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 src/jvmMain/kotlin/JvmMoney.kt create mode 100644 src/nonJvmMain/kotlin/NonJvmMoney.kt diff --git a/src/jvmMain/kotlin/JvmMoney.kt b/src/jvmMain/kotlin/JvmMoney.kt new file mode 100644 index 0000000..e31e9e8 --- /dev/null +++ b/src/jvmMain/kotlin/JvmMoney.kt @@ -0,0 +1,100 @@ +/* + * Copyright 2024 Kazimierz Pogoda / Xemantic + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.xemantic.ai.money + +import java.math.BigDecimal +import kotlin.minus +import kotlin.plus +import kotlin.times + +public class JvmMoney(private val value: BigDecimal) : Money { + + override fun plus(amount: Money): Money = JvmMoney( + value + (amount as JvmMoney).value + ) + + override fun minus(amount: Money): Money = JvmMoney( + value - (amount as JvmMoney).value + ) + + override fun times(amount: Money): Money = JvmMoney( + (value * (amount as JvmMoney).value).stripTrailingZeros() + ) + + override fun times(ratio: Money.Ratio): Money = JvmMoney( + (value * (ratio as JvmRatio).value).stripTrailingZeros() + ) + + override fun compareTo( + other: Money + ): Int = value.compareTo((other as JvmMoney).value) + + override fun toString(): String { + return value.toPlainString() + } + + override fun equals( + other: Any? + ): Boolean = (other != null) + && (other is JvmMoney) + && (value == other.value) + + override fun hashCode(): Int = value.hashCode() + + internal class JvmRatio(internal val value: BigDecimal) : Money.Ratio { + + override fun times(amount: Money): Money = JvmMoney( + (value * (amount as JvmMoney).value).stripTrailingZeros() + ) + + override fun toString(): String { + return value.toPlainString() + } + + override fun equals( + other: Any? + ): Boolean = (other != null) + && (other is JvmRatio) + && (value == other.value) + + override fun hashCode(): Int = value.hashCode() + + } + +} + +public actual fun Money(amount: String): Money = JvmMoney( + BigDecimal(amount).stripTrailingZeros() +) + +@Suppress("ObjectPropertyName") +private val _ZERO = JvmMoney(BigDecimal.ZERO) +public actual val Money.Companion.ZERO: Money get() = _ZERO + +@Suppress("ObjectPropertyName") +private val _ONE = JvmMoney(BigDecimal.ONE) +public actual val Money.Companion.ONE: Money get() = _ONE + +public actual fun Money.Companion.Ratio( + value: String +): Money.Ratio = JvmMoney.JvmRatio( + BigDecimal(value).stripTrailingZeros() +) + +@Suppress("ObjectPropertyName") +private val _RATIO_ONE = JvmMoney.JvmRatio(BigDecimal.ONE) +public actual val Money.Ratio.Companion.ONE: Money.Ratio get() = _RATIO_ONE diff --git a/src/nonJvmMain/kotlin/NonJvmMoney.kt b/src/nonJvmMain/kotlin/NonJvmMoney.kt new file mode 100644 index 0000000..47983be --- /dev/null +++ b/src/nonJvmMain/kotlin/NonJvmMoney.kt @@ -0,0 +1,97 @@ +/* + * Copyright 2024 Kazimierz Pogoda / Xemantic + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.xemantic.ai.money + +import com.ionspin.kotlin.bignum.decimal.BigDecimal + +public class NonJvmMoney(private val value: BigDecimal) : Money { + + override fun plus(amount: Money): Money = NonJvmMoney( + value + (amount as NonJvmMoney).value + ) + + override fun minus(amount: Money): Money = NonJvmMoney( + value - (amount as NonJvmMoney).value + ) + + override fun times(amount: Money): Money = NonJvmMoney( + (value * (amount as NonJvmMoney).value) + ) + + override fun times(ratio: Money.Ratio): Money = NonJvmMoney( + (value * (ratio as NativeRatio).value) + ) + + override fun compareTo( + other: Money + ): Int = value.compareTo((other as NonJvmMoney).value) + + override fun toString(): String { + return value.toPlainString() + } + + override fun equals( + other: Any? + ): Boolean = (other != null) + && (other is NonJvmMoney) + && (value == other.value) + + override fun hashCode(): Int = value.hashCode() + + internal class NativeRatio(internal val value: BigDecimal) : Money.Ratio { + + override fun times(amount: Money): Money = NonJvmMoney( + (value * (amount as NonJvmMoney).value) + ) + + override fun toString(): String { + return value.toPlainString() + } + + override fun equals( + other: Any? + ): Boolean = (other != null) + && (other is NativeRatio) + && (value == other.value) + + override fun hashCode(): Int = value.hashCode() + + } + +} + +public actual fun Money(amount: String): Money = NonJvmMoney( + BigDecimal.parseString(amount) +) + +@Suppress("ObjectPropertyName") +private val _ZERO = NonJvmMoney(BigDecimal.ZERO) +public actual val Money.Companion.ZERO: Money get() = _ZERO + +@Suppress("ObjectPropertyName") +private val _ONE = NonJvmMoney(BigDecimal.ONE) +public actual val Money.Companion.ONE: Money get() = _ONE + +public actual fun Money.Companion.Ratio( + value: String +): Money.Ratio = NonJvmMoney.NativeRatio( + BigDecimal.parseString(value) +) + +@Suppress("ObjectPropertyName") +private val _RATIO_ONE = NonJvmMoney.NativeRatio(BigDecimal.ONE) +public actual val Money.Ratio.Companion.ONE: Money.Ratio get() = _RATIO_ONE