I am trying to abstract from the android.os.Bundle API, trying to generate Bundles this way:
case class MyClass( a: Int, b: String ) val mc = MyClass( 3, "5" ) implicit val bundleable = Bundle.from[MyClass]() val bundle = bundleable.write( mc ) assert( mc == bundleable.read( bundle ) )
Converting the case class to LabelledGeneric and writing key value pairs to the Bundle is simple. But I cannot find a way to extract the values โโfrom the Bundle back to the original type. I think that numerous JSON libraries have already solved this problem, but I still canโt find the key to how to proceed.
object Bundle { def from[T] = new { def apply[LG <: HList, K <: HList, N <: Nat]()( implicit lg: LabelledGeneric.Aux[T, LG], l: Length.Aux[LG, N], k: Keys.Aux[LG, K], lfw: LeftFolder.Aux[LG, Bundle, fold.write.type, Bundle], //lfr: LeftFolder.Aux[K, Bundle, fold.read.type, LG], ti: ToInt[N] ) = new Bundleable[T] { override def write( value: T ): Bundle = { lg.to( value ).foldLeft( new Bundle( toInt[N] ) )( fold.write ) } override def read( bundle: Bundle ): T = ??? } } object fold { object write extends Poly2 { implicit def default[K <: Symbol, V: Bundleize]( implicit key: Witness.Aux[K] ): Case.Aux[Bundle, FieldType[K, V], Bundle] = { at { ( bundle, value ) โ implicitly[Bundleize[V]].write( key.value.name, value, bundle ) bundle } } } object read extends Poly2 { ??? } } } /** * Read or write a single value from/into a Bundle */ trait Bundleize[T] { def read( key: String, bundle: Bundle ): T def write( key: String, value: T, bundle: Bundle ): Unit } /** * Transformation T <> Bundle */ trait Bundleable[T] { def read( bundle: Bundle ): T def write( value: T ): Bundle }
Also, is there a way to restructure the code in such a way that I can write Bundle.from[MyClass] and not Bundle.from[MyClass]() (omitting the parentheses)?