What I actually want is to have the flexibility to...
# announcements
p
What I actually want is to have the flexibility to use these as extension functions so my implementing classes can just call .toBundle()
l
paulwoitaschek: if the class has to implement it anyway, why do you need it to be an extension function?
p
The class can't implement it as fromBundle is creating instances so it's kind of static
l
ah sorry. of course 🙈
p
What I need acutally is some kind of a static interface
I could split the interface and let the class implement bundler and the companion object unbundler
But that's still inconvenient as I now have this implicit contract
l
something like this?
Copy code
fun <T,R: Bundler> T.fromBundle(b: Bundle) : R {
    return UnBundler().fromBundle(b) //will throw if not possible
}
val thing: Thing = fromBundle(extras)
ah this doesn’t really work because generics. 😞 could imagine that it works with
reified
though
ok this works:
Copy code
abstract class UnBundler(val canHandle: KClass<*>) {

    companion object {
        val unbundlers: MutableList<UnBundler> = arrayListOf()

        inline fun <reified R> unBundle(b: Bundle): R {
            val unbundler = unbundlers.find { it.canHandleClass(R::class) }

            if (unbundler == null)
                throw UnBundlerNotRegistered()

            return unbundler.unbundle(b) as R

        }
    }

    fun canHandleClass(kClass: KClass<*>): Boolean {
        return kClass == canHandle
    }

    abstract fun unbundle(b: Bundle): Any

}

...

inline fun <reified R: Bundler> Any.fromBundle(b: Bundle) : R {
    return UnBundler.unBundle<R>(b)
}
Of course, just as you said, you have to manage two classes. Register a new
UnBundler
for each new class that implements
Bundler