moko-kswift
moko-kswift copied to clipboard
Enhancement: Convert sealed classes with deep hierarchy into single Swift enum
Plugin version I've used
plugins {
id("dev.icerock.moko.kswift") version "0.3.0"
}
Problem
If we define a sealed class with deep hierarchy (when the sealed class has several inheritor sealed classes), moko-kswift will generate different enums for every sealed class.
In Kotlin:
sealed class SealedWithDeepHierarchy {
abstract val param: String
sealed class LocalTrigger : SealedWithDeepHierarchy() {
object First : LocalTrigger() {
override val param: String = "first"
}
}
sealed class RemoteTrigger : SealedWithDeepHierarchy() {
class Second(override val param: String) : RemoteTrigger()
data class Third(override val param: String) : RemoteTrigger()
}
}
// On the Kotlin side this hierarchy splitted into different branches of 'when'-expression
private fun example(s: SealedWithDeepHierarchy) {
when (s) {
SealedWithDeepHierarchy.LocalTrigger.First -> TODO()
is SealedWithDeepHierarchy.RemoteTrigger.Second -> TODO()
is SealedWithDeepHierarchy.RemoteTrigger.Third -> TODO()
}
}
moko-kswift will generate bridge code for every sealed class separately:
public enum SealedWithDeepHierarchyLocalTriggerKs {
case first
public init(_ obj: SealedWithDeepHierarchy.LocalTrigger) {
if obj is HHMobileSdk.SealedWithDeepHierarchy.LocalTriggerFirst {
self = .first
} else {
fatalError("SealedWithDeepHierarchyLocalTriggerKs not syncronized with SealedWithDeepHierarchy.LocalTrigger class")
}
}
}
public enum SealedWithDeepHierarchyRemoteTriggerKs {
case second(SealedWithDeepHierarchy.RemoteTriggerSecond)
case third(SealedWithDeepHierarchy.RemoteTriggerThird)
public init(_ obj: SealedWithDeepHierarchy.RemoteTrigger) {
if let obj = obj as? HHMobileSdk.SealedWithDeepHierarchy.RemoteTriggerSecond {
self = .second(obj)
} else if let obj = obj as? HHMobileSdk.SealedWithDeepHierarchy.RemoteTriggerThird {
self = .third(obj)
} else {
fatalError("SealedWithDeepHierarchyRemoteTriggerKs not syncronized with SealedWithDeepHierarchy.RemoteTrigger class")
}
}
}
public enum SealedWithDeepHierarchyKs {
case localTrigger(SealedWithDeepHierarchy.LocalTrigger)
case remoteTrigger(SealedWithDeepHierarchy.RemoteTrigger)
public init(_ obj: SealedWithDeepHierarchy) {
if let obj = obj as? HHMobileSdk.SealedWithDeepHierarchy.LocalTrigger {
self = .localTrigger(obj)
} else if let obj = obj as? HHMobileSdk.SealedWithDeepHierarchy.RemoteTrigger {
self = .remoteTrigger(obj)
} else {
fatalError("SealedWithDeepHierarchyKs not syncronized with SealedWithDeepHierarchy class")
}
}
}
So in Swift you will use it like this:
func mokoKswiftUsage(c: SealedWithDeepHierarchy) {
switch SealedWithDeepHierarchyKs(c) {
case let .localTrigger(tr):
switch SealedWithDeepHierarchyLocalTriggerKs(tr) {
case .first:
<#code#>
}
case let .remoteTrigger(tr):
switch SealedWithDeepHierarchyRemoteTriggerKs(tr) {
case .second(_):
<#code#>
case .third(_):
<#code#>
}
}
}
It would be great, if in such case moko-kswift will generate single enum for more transparent usage, e.g:
func mokoKswiftUsage(c: SealedWithDeepHierarchy) {
switch SealedWithDeepHierarchyKs(c) {
case .localTriggerFirst:
<code>
case .remoteTriggerSecond(_):
<code>
case .remoteTriggerThird(_):
<code>
}