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 @@
-
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
index 931b96c3..16660f1d 100644
--- a/.idea/runConfigurations.xml
+++ b/.idea/runConfigurations.xml
@@ -5,8 +5,12 @@
+
+
+
+
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()!!
}
}