sto cercando di astrarre il android.os.Bundle
API, con l'obiettivo di generare pacchetti in questo modo:Trasformare i dati da una memoria runtime per una classe case
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))
Conversione della classe caso ad un LabelledGeneric
e scrivere la chiave coppie di valori allo Bundle
è semplice. Ma non riesco a trovare un modo per estrarre i valori da un Bundle
nel loro tipo originale. Immagino che le numerose librerie JSON là fuori abbiano già risolto questo problema, ma non riesco ancora a trovare un indizio su come procedere.
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
}
Inoltre, c'è un modo per ristrutturare il codice in modo tale, che posso scrivere Bundle.from[MyClass]
, piuttosto che Bundle.from[MyClass]()
(omettendo le parentesi)?
Hai ragione a pensare a questo come un problema di serializzazione (de), dove fasci sono l'obiettivo di serializzazione piuttosto che JSON. Un esempio che potrebbe aiutarti a procedere è [questo] (https://github.com/milessabin/shapeless/blob/master/examples/src/main/scala/shapeless/examples/sexp.scala#L34) che ha come target un S-expresssion like representation ... dovresti essere in grado di adattare questo per i bundle. –
Grazie mille, non posso credere quanto sia stato facile. La parte più difficile è stata capire cosa ha in comune il codice di esempio S-expression con il mio esempio. L'implementazione funzionante si è ridotta a copia e incolla. Pubblicherò una soluzione di lavoro pulita quando ho finito. – Taig