Closed
Description
This is a placeholder bug to track potentially converting the serialization api to use generators (#7746). Once we have generators, We'll be able to write a serializer like this:
struct A {
a: int,
b: B,
}
Struct B {
c: ~str,
d: ~[int],
}
impl serialize::Encodable for A {
fn encode_iter<'a>(&'a self) -> Option<Value<'a>> {
yield StructStart("A");
yield StructField("a", 0);
yield Int(self.a);
yield StructField("b", 1);
for value in self.b.encode_iter() { yield value; }
yield StructEnd;
}
}
impl serialize::Encodable for B {
fn encode_iter<'a>(&'a self) -> Option<Value<'a>> {
yield StructStart("B");
yield StructField("c", 0);
yield String(self.c);
yield StructField("d", 1);
for value in self.d.encode_iter() { yield value; }
yield StructEnd;
}
}
A Deserializer would also be pretty simple:
struct PrettyPrinter<T> {
it: T
}
impl<T: Iterator<Value>> serialize::Decoder<()> for PrettyPrinter {
fn decode(&mut self) -> () {
match self.it.next() {
None => fail!(),
Some(Int(x)) => printfln!("%?", x),
Some(Str(x)) => printfln!("%?", x),
Some(StructStart(name)) => {
printfln!("%s {", name);
self.decode_struct()
}
...
}
}
fn decode_struct(&mut self) {
match self.it.next() {
Some(StructField(name, idx)) => {
if idx != 0 { printfln!(","); }
printfln!("%s:", name);
self.decode();
}
Some(StructEnd) => printfln!("}"),
_ => fail!(),
}
}
...
}
There are two advantages to this conversion. First, it's easier for rustc to optimize iterator-based code instead of recursive-closure-based code. Second, it allows for a serializer like extra::json::Encoder
peek into the iterator stream to validate that a map key is actually a string. This would fix #8883.
Metadata
Metadata
Assignees
Labels
No labels