uniflow-kt / uniflow-kt

Uniflow 🦄 - Simple Unidirectional Data Flow for Android & Kotlin, using Kotlin coroutines and open to functional programming

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Throwable is not comparable :/

arnaudgiuliani opened this issue · comments

Hello,

the fact that Throwable is not comparable as is in Kotlin is a big problem. It forces us to make some workaround to make it "comparable".

If we check what is a comparable:

/**
 * The base class for all errors and exceptions. Only instances of this class can be thrown or caught.
 *
 * @param message the detail message string.
 * @param cause the cause of this throwable.
 */
public open class Throwable(open val message: String?, open val cause: Throwable?) {
    constructor(message: String?) : this(message, null)

    constructor(cause: Throwable?) : this(cause?.toString(), cause)

    constructor() : this(null, null)
}

I would propose then a data class type to encapsulate Throwable:

open class ThrowableKt(val message: String? = null, val cause: ThrowableKt? = null) {

    constructor(message: String? = null) : this(message, null as? ThrowableKt)
    constructor(message: String? = null, cause: Throwable? = null) : this(message, cause?.toThrowableKt())
    constructor(message: String? = null, cause: Exception? = null) : this(message, cause?.toThrowableKt())

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as ThrowableKt

        if (message != other.message) return false
        if (cause != other.cause) return false

        return true
    }

    override fun hashCode(): Int {
        var result = message?.hashCode() ?: 0
        result = 42 * result + (cause?.hashCode() ?: 0)
        return result
    }

    override fun toString(): String = "ThrowableKt(message='$message',cause=$cause)"
}

fun Throwable.toThrowableKt(): ThrowableKt {
    return ThrowableKt(message, cause?.toThrowableKt())
}

fun throwableKt(t: Throwable) = t.toThrowableKt()

What do you think?

it would make all state comparison more easy, and also less painful for users to implement their own state failure as they don't need to override Equals to compare Exception/Throwable

state and event can be written like that:

data class Failed(val message: String? = null, val error: ThrowableKt? = null, val state: UIState? = null) : UIState() {
        constructor(message: String? = null) : this(message, null as ThrowableKt)
        constructor(message: String? = null, state: UIState? = null) : this(message, null as ThrowableKt, state)
        constructor(message: String? = null, error: Throwable? = null, state: UIState? = null) : this(message, error?.toThrowableKt(), state)
        constructor(message: String? = null, error: Exception? = null, state: UIState? = null) : this(message, error?.toThrowableKt(), state)
    }

follow on PR