diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 00000000..4a53bee8 --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index 98dd9bb5..52631507 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -7,6 +7,6 @@ diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 4bf808cb..7ddfc9ed 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -3,8 +3,6 @@ - - diff --git a/buildSrc/gradle/wrapper/gradle-wrapper.jar b/buildSrc/gradle/wrapper/gradle-wrapper.jar index a4b76b95..9bbc975c 100644 Binary files a/buildSrc/gradle/wrapper/gradle-wrapper.jar and b/buildSrc/gradle/wrapper/gradle-wrapper.jar differ diff --git a/core/src/main/java/com/hoc/flowmvi/core/EitherNes.kt b/core/src/main/java/com/hoc/flowmvi/core/EitherNes.kt index 0cd43881..0f8af29c 100644 --- a/core/src/main/java/com/hoc/flowmvi/core/EitherNes.kt +++ b/core/src/main/java/com/hoc/flowmvi/core/EitherNes.kt @@ -1,9 +1,11 @@ package com.hoc.flowmvi.core import arrow.core.Either +import arrow.core.NonEmptySet import arrow.core.left +import arrow.core.nonEmptySetOf import arrow.core.right -import com.hoc.flowmvi.core.NonEmptySet.Companion.toNonEmptySetOrNull +import arrow.core.toNonEmptySetOrNull import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -17,7 +19,7 @@ typealias EitherNes = Either, A> inline fun A.rightNes(): EitherNes = this.right() @Suppress("NOTHING_TO_INLINE") -inline fun E.leftNes(): EitherNes = NonEmptySet.of(this).left() +inline fun E.leftNes(): EitherNes = nonEmptySetOf(this).left() @OptIn(ExperimentalContracts::class) inline fun Either.Companion.zipOrAccumulateNonEmptySet( diff --git a/core/src/main/java/com/hoc/flowmvi/core/NonEmptySet.kt b/core/src/main/java/com/hoc/flowmvi/core/NonEmptySet.kt deleted file mode 100644 index 315af8b8..00000000 --- a/core/src/main/java/com/hoc/flowmvi/core/NonEmptySet.kt +++ /dev/null @@ -1,70 +0,0 @@ -package com.hoc.flowmvi.core - -/** - * `NonEmptySet` is a data type used to model sets that guarantee to have at least one value. - */ -class NonEmptySet - @Throws(IllegalArgumentException::class) - private constructor( - val set: Set, - ) : AbstractSet() { - init { - require(set.isNotEmpty()) { "Set must not be empty" } - require(set !is NonEmptySet) { "Set must not be NonEmptySet" } - } - - override val size: Int get() = set.size - - override fun iterator(): Iterator = set.iterator() - - override fun isEmpty(): Boolean = false - - operator fun plus(l: NonEmptySet<@UnsafeVariance T>): NonEmptySet = NonEmptySet(set + l.set) - - @Suppress("RedundantOverride") - override fun equals(other: Any?): Boolean = super.equals(other) - - @Suppress("RedundantOverride") - override fun hashCode(): Int = super.hashCode() - - override fun toString(): String = "NonEmptySet(${set.joinToString()})" - - companion object { - /** - * Creates a [NonEmptySet] from the given [Collection]. - * @return null if [this] is empty. - */ - @JvmStatic - fun Collection.toNonEmptySetOrNull(): NonEmptySet? = if (isEmpty()) null else NonEmptySet(toSet()) - - /** - * Creates a [NonEmptySet] from the given [Set]. - * @return null if [this] is empty. - */ - @JvmStatic - fun Set.toNonEmptySetOrNull(): NonEmptySet? = - (this as? NonEmptySet) - ?: if (isEmpty()) null else NonEmptySet(this) - - /** - * Creates a [NonEmptySet] from the given values. - */ - @JvmStatic - fun of( - element: T, - vararg elements: T, - ): NonEmptySet = - NonEmptySet( - buildSet(capacity = 1 + elements.size) { - add(element) - addAll(elements) - }, - ) - - /** - * Creates a [NonEmptySet] that contains only the specified [element]. - */ - @JvmStatic - fun of(element: T): NonEmptySet = NonEmptySet(setOf(element)) - } - } diff --git a/core/src/test/java/com/hoc/flowmvi/core/NonEmptySetTest.kt b/core/src/test/java/com/hoc/flowmvi/core/NonEmptySetTest.kt deleted file mode 100644 index 040bfc12..00000000 --- a/core/src/test/java/com/hoc/flowmvi/core/NonEmptySetTest.kt +++ /dev/null @@ -1,156 +0,0 @@ -package com.hoc.flowmvi.core - -import com.hoc.flowmvi.core.NonEmptySet.Companion.toNonEmptySetOrNull -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertNotNull -import kotlin.test.assertNull -import kotlin.test.assertSame - -class NonEmptySetTest { - @Test - fun `test List#toNonEmptySetOrNull returns null when input is empty`() { - assertNull(emptyList().toNonEmptySetOrNull()) - } - - @Test - fun `test List#toNonEmptySetOrNull returns NonEmptySet when input is not empty`() { - assertEquals( - setOf(1), - assertNotNull( - listOf(1).toNonEmptySetOrNull(), - ), - ) - - assertEquals( - setOf(1, 2), - assertNotNull( - listOf(1, 2).toNonEmptySetOrNull(), - ), - ) - - assertEquals( - setOf(1), - assertNotNull( - listOf(1, 1).toNonEmptySetOrNull(), - ), - ) - } - - @Test - fun `test Set#toNonEmptySetOrNull returns null when input is empty`() { - assertNull(emptySet().toNonEmptySetOrNull()) - } - - @Test - fun `test Set#toNonEmptySetOrNull returns NonEmptySet when input is not empty`() { - assertEquals( - setOf(1), - assertNotNull( - setOf(1).toNonEmptySetOrNull(), - ), - ) - - assertEquals( - setOf(1, 2), - assertNotNull( - setOf(1, 2).toNonEmptySetOrNull(), - ), - ) - - assertEquals( - setOf(1), - assertNotNull( - setOf(1, 1).toNonEmptySetOrNull(), - ), - ) - } - - @Test - fun `test Set#toNonEmptySetOrNull returns itself when the input is NonEmptySet`() { - val input = NonEmptySet.of(1) - - assertSame( - input, - input.toNonEmptySetOrNull(), - ) - } - - @Test - fun `test NonEmptySet#of`() { - assertEquals( - setOf(1), - NonEmptySet.of(1), - ) - - assertEquals( - setOf(1, 2), - NonEmptySet.of(1, 2), - ) - - assertEquals( - setOf(1), - NonEmptySet.of(1, 1), - ) - } - - @Test - fun `test NonEmptySet#equals`() { - assertEquals( - NonEmptySet.of(1), - NonEmptySet.of(1), - ) - assertEquals( - NonEmptySet.of(1, 2), - NonEmptySet.of(1, 2), - ) - assertEquals( - NonEmptySet.of(1, 1), - NonEmptySet.of(1, 1), - ) - - assertEquals( - listOf(1, 2).toNonEmptySetOrNull(), - listOf(1, 2).toNonEmptySetOrNull(), - ) - - assertEquals( - hashSetOf(1, 2).toNonEmptySetOrNull(), - linkedSetOf(1, 2).toNonEmptySetOrNull(), - ) - assertEquals( - setOf(1, 2).toNonEmptySetOrNull(), - setOf(1, 2).toNonEmptySetOrNull(), - ) - } - - @Test - fun `test NonEmptySet#hashCode`() { - assertEquals( - NonEmptySet.of(1).hashCode(), - NonEmptySet.of(1).hashCode(), - ) - assertEquals( - NonEmptySet.of(1, 2).hashCode(), - NonEmptySet.of(1, 2).hashCode(), - ) - assertEquals( - NonEmptySet.of(1, 1).hashCode(), - NonEmptySet.of(1, 1).hashCode(), - ) - - assertEquals( - listOf(1, 2).toNonEmptySetOrNull()!!.hashCode(), - listOf(1, 2).toNonEmptySetOrNull()!!.hashCode(), - ) - - assertEquals( - hashSetOf(1, 2).toNonEmptySetOrNull()!!.hashCode(), - linkedSetOf(1, 2).toNonEmptySetOrNull()!!.hashCode(), - ) - assertEquals( - setOf(1, 2).toNonEmptySetOrNull()!!.hashCode(), - setOf(1, 2).toNonEmptySetOrNull()!!.hashCode(), - ) - } -} diff --git a/data/src/test/java/com/hoc/flowmvi/data/mapper/UserErrorMapperTest.kt b/data/src/test/java/com/hoc/flowmvi/data/mapper/UserErrorMapperTest.kt index 489308fd..27b7844d 100644 --- a/data/src/test/java/com/hoc/flowmvi/data/mapper/UserErrorMapperTest.kt +++ b/data/src/test/java/com/hoc/flowmvi/data/mapper/UserErrorMapperTest.kt @@ -1,6 +1,6 @@ package com.hoc.flowmvi.data.mapper -import com.hoc.flowmvi.core.NonEmptySet +import arrow.core.nonEmptySetOf import com.hoc.flowmvi.data.remote.ErrorResponse import com.hoc.flowmvi.domain.model.UserError import com.hoc.flowmvi.domain.model.UserValidationError @@ -55,8 +55,8 @@ class UserErrorMapperTest { assertEquals(UserError.UserNotFound("1"), errorMapper(UserError.UserNotFound("1"))) assertEquals(UserError.InvalidId("1"), errorMapper(UserError.InvalidId("1"))) assertEquals( - UserError.ValidationFailed(NonEmptySet.of(UserValidationError.INVALID_EMAIL_ADDRESS)), - errorMapper(UserError.ValidationFailed(NonEmptySet.of(UserValidationError.INVALID_EMAIL_ADDRESS))), + UserError.ValidationFailed(nonEmptySetOf(UserValidationError.INVALID_EMAIL_ADDRESS)), + errorMapper(UserError.ValidationFailed(nonEmptySetOf(UserValidationError.INVALID_EMAIL_ADDRESS))), ) assertEquals(UserError.ServerError, errorMapper(UserError.ServerError)) assertEquals(UserError.Unexpected, errorMapper(UserError.Unexpected)) diff --git a/domain/src/main/java/com/hoc/flowmvi/domain/model/UserError.kt b/domain/src/main/java/com/hoc/flowmvi/domain/model/UserError.kt index d3c075b2..9d869352 100644 --- a/domain/src/main/java/com/hoc/flowmvi/domain/model/UserError.kt +++ b/domain/src/main/java/com/hoc/flowmvi/domain/model/UserError.kt @@ -1,9 +1,11 @@ package com.hoc.flowmvi.domain.model -import com.hoc.flowmvi.core.NonEmptySet +import arrow.core.NonEmptySet sealed class UserError : Throwable() { - object NetworkError : UserError() + data object NetworkError : UserError() { + private fun readResolve(): Any = NetworkError + } data class UserNotFound( val id: String, @@ -16,6 +18,12 @@ sealed class UserError : Throwable() { data class ValidationFailed( val errors: NonEmptySet, ) : UserError() - object ServerError : UserError() - object Unexpected : UserError() + + data object ServerError : UserError() { + private fun readResolve(): Any = ServerError + } + + data object Unexpected : UserError() { + private fun readResolve(): Any = Unexpected + } } diff --git a/domain/src/main/java/com/hoc/flowmvi/domain/model/UserValidationError.kt b/domain/src/main/java/com/hoc/flowmvi/domain/model/UserValidationError.kt index 623b6838..fca19b3e 100644 --- a/domain/src/main/java/com/hoc/flowmvi/domain/model/UserValidationError.kt +++ b/domain/src/main/java/com/hoc/flowmvi/domain/model/UserValidationError.kt @@ -1,8 +1,8 @@ package com.hoc.flowmvi.domain.model +import arrow.core.NonEmptySet +import arrow.core.toNonEmptySetOrNull import com.hoc.flowmvi.core.EitherNes -import com.hoc.flowmvi.core.NonEmptySet -import com.hoc.flowmvi.core.NonEmptySet.Companion.toNonEmptySetOrNull import com.hoc.flowmvi.core.leftNes enum class UserValidationError { @@ -14,14 +14,6 @@ enum class UserValidationError { val asLeftNes: EitherNes = leftNes() companion object { - /** - * Use this instead of [values()] for more performant. - * See [KT-48872](https://youtrack.jetbrains.com/issue/KT-48872) - */ - @JvmField - val VALUES: List = values().asList() - - @JvmField - val VALUES_SET: NonEmptySet = VALUES.toNonEmptySetOrNull()!! + val VALUES_SET: NonEmptySet = UserValidationError.entries.toNonEmptySetOrNull()!! } }