Skip to content

Commit

Permalink
feat(#31): add div operations for AnyInt
Browse files Browse the repository at this point in the history
  • Loading branch information
LVMVRQUXL committed Mar 15, 2023
1 parent 17201cd commit 73b031d
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 2 deletions.
4 changes: 2 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ class NotEmptyList<out E> : NotEmptyCollection<E>
class NotEmptySet<out E> : NotEmptyCollection<E>
```

- Binary operations (`plus`, `minus`, `times`) for the `AnyInt` hierarchy (issue
[#31](https://github.com/kotools/types/issues/31)).
- Binary operations (`plus`, `minus`, `times`, `div`) for the `AnyInt` hierarchy
(issue [#31](https://github.com/kotools/types/issues/31)).

```kotlin
val x: AnyInt = NonZeroInt.random()
Expand Down
7 changes: 7 additions & 0 deletions src/commonMain/kotlin/kotools/types/number/AnyInt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ public operator fun AnyInt.times(other: Int): Int = toInt() * other
@SinceKotoolsTypes("4.1")
public operator fun AnyInt.times(other: AnyInt): Int = toInt() * other

/**
* Divides this integer by the [other] one, truncating the result to an integer
* that is closer to [zero][ZeroInt].
*/
@SinceKotoolsTypes("4.1")
public operator fun AnyInt.div(other: NonZeroInt): Int = toInt() / other

internal sealed interface AnyIntSerializer<I : AnyInt> : KSerializer<I> {
val serialName: Result<NotBlankString>

Expand Down
22 changes: 22 additions & 0 deletions src/commonMain/kotlin/kotools/types/number/NegativeInt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,28 @@ public sealed interface NegativeInt : AnyInt {
override fun toString(): String
}

/**
* Divides this integer by the [other] one, truncating the result to an integer
* that is closer to [zero][ZeroInt].
*/
@SinceKotoolsTypes("4.1")
public operator fun NegativeInt.div(other: StrictlyPositiveInt): NegativeInt {
val result: Int = toInt() / other
return result.toNegativeInt()
.getOrThrow()
}

/**
* Divides this integer by the [other] one, truncating the result to an integer
* that is closer to [zero][ZeroInt].
*/
@SinceKotoolsTypes("4.1")
public operator fun NegativeInt.div(other: StrictlyNegativeInt): PositiveInt {
val result: Int = toInt() / other
return result.toPositiveInt()
.getOrThrow()
}

/**
* Returns this number as an encapsulated [NegativeInt], which may involve
* rounding or truncation, or returns an encapsulated [IllegalArgumentException]
Expand Down
7 changes: 7 additions & 0 deletions src/commonMain/kotlin/kotools/types/number/NonZeroInt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ public sealed interface NonZeroInt : AnyInt {
override fun toString(): String
}

/**
* Divides this integer by the [other] one, truncating the result to an integer
* that is closer to [zero][ZeroInt].
*/
@SinceKotoolsTypes("4.1")
public operator fun Int.div(other: NonZeroInt): Int = this / other.toInt()

/**
* Returns this number as an encapsulated [NonZeroInt], which may involve
* rounding or truncation, or returns an encapsulated [IllegalArgumentException]
Expand Down
22 changes: 22 additions & 0 deletions src/commonMain/kotlin/kotools/types/number/PositiveInt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ public sealed interface PositiveInt : AnyInt {
override fun toString(): String
}

/**
* Divides this integer by the [other] one, truncating the result to an integer
* that is closer to [zero][ZeroInt].
*/
@SinceKotoolsTypes("4.1")
public operator fun PositiveInt.div(other: StrictlyPositiveInt): PositiveInt {
val result: Int = toInt() / other
return result.toPositiveInt()
.getOrThrow()
}

/**
* Divides this integer by the [other] one, truncating the result to an integer
* that is closer to [zero][ZeroInt].
*/
@SinceKotoolsTypes("4.1")
public operator fun PositiveInt.div(other: StrictlyNegativeInt): NegativeInt {
val result: Int = toInt() / other
return result.toNegativeInt()
.getOrThrow()
}

/**
* Returns this number as an encapsulated [PositiveInt], which may involve
* rounding or truncation, or returns an encapsulated [IllegalArgumentException]
Expand Down
8 changes: 8 additions & 0 deletions src/commonTest/kotlin/kotools/types/number/AnyIntTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ class AnyIntTest {
val result: Int = x * y
result shouldEqual x.toInt() * y.toInt()
}

@Test
fun div_should_pass_with_a_NonZeroInt() {
val x: AnyInt = PositiveInt.random()
val y: NonZeroInt = NonZeroInt.random()
val result: Int = x / y
result shouldEqual x.toInt() / y.toInt()
}
}

class AnyIntSerializerTest {
Expand Down
16 changes: 16 additions & 0 deletions src/commonTest/kotlin/kotools/types/number/NegativeIntTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ class NegativeIntCompanionTest {
}

class NegativeIntTest {
@Test
fun div_should_return_a_NegativeInt_with_a_StrictlyPositiveInt() {
val x: NegativeInt = NegativeInt.random()
val y: StrictlyPositiveInt = StrictlyPositiveInt.random()
val result: NegativeInt = x / y
result.toInt() shouldEqual x.toInt() / y.toInt()
}

@Test
fun div_should_return_a_PositiveInt_with_a_StrictlyNegativeInt() {
val x: NegativeInt = NegativeInt.random()
val y: StrictlyNegativeInt = StrictlyNegativeInt.random()
val result: PositiveInt = x / y
result.toInt() shouldEqual x.toInt() / y.toInt()
}

@Test
fun number_toNegativeInt_should_pass_with_a_negative_Int() {
val value: Number = NegativeInt.random()
Expand Down
9 changes: 9 additions & 0 deletions src/commonTest/kotlin/kotools/types/number/NonZeroIntTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotools.types.Package
import kotools.types.shouldEqual
import kotools.types.shouldHaveAMessage
import kotools.types.shouldNotEqual
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertFailsWith

Expand All @@ -33,6 +34,14 @@ class NonZeroIntCompanionTest {
}

class NonZeroIntTest {
@Test
fun int_div_should_pass_with_a_NonZeroInt() {
val x: Int = Random.nextInt()
val y: NonZeroInt = NonZeroInt.random()
val result: Int = x / y
result shouldEqual x / y.toInt()
}

@Test
fun number_toNonZeroInt_should_pass_with_an_Int_other_than_zero() {
val value: Number = NonZeroInt.random()
Expand Down
16 changes: 16 additions & 0 deletions src/commonTest/kotlin/kotools/types/number/PositiveIntTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,22 @@ class PositiveIntCompanionTest {
}

class PositiveIntTest {
@Test
fun div_should_return_a_PositiveInt_with_a_StrictlyPositiveInt() {
val x: PositiveInt = PositiveInt.random()
val y: StrictlyPositiveInt = StrictlyPositiveInt.random()
val result: PositiveInt = x / y
result.toInt() shouldEqual x.toInt() / y.toInt()
}

@Test
fun div_should_return_a_NegativeInt_with_a_StrictlyNegativeInt() {
val x: PositiveInt = PositiveInt.random()
val y: StrictlyNegativeInt = StrictlyNegativeInt.random()
val result: NegativeInt = x / y
result.toInt() shouldEqual x.toInt() / y.toInt()
}

@Test
fun number_toPositiveInt_should_pass_with_a_positive_Int() {
val expected: Number = PositiveInt.random().toInt()
Expand Down

0 comments on commit 73b031d

Please sign in to comment.