Module syntax::ext::deriving::encodable[src]

The compiler code necessary to implement the #[deriving(Encodable)] (and Decodable, in decodable.rs) extension. The idea here is that type-defining items may be tagged with #[deriving(Encodable, Decodable)].

For example, a type like:

#[deriving(Encodable, Decodable)]
struct Node { id: uint }

would generate two implementations like:

impl<S:serialize::Encoder> Encodable<S> for Node {
    fn encode(&self, s: &S) {
        s.emit_struct("Node", 1, || {
            s.emit_field("id", 0, || s.emit_uint(self.id))
        })
    }
}

impl<D:Decoder> Decodable for node_id {
    fn decode(d: &D) -> Node {
        d.read_struct("Node", 1, || {
            Node {
                id: d.read_field("x".to_string(), 0, || decode(d))
            }
        })
    }
}

Other interesting scenarios are whe the item has type parameters or references other non-built-in types. A type definition like:

#[deriving(Encodable, Decodable)]
struct spanned<T> { node: T, span: Span }

would yield functions like:

    impl<
        S: Encoder,
        T: Encodable<S>
    > spanned<T>: Encodable<S> {
        fn encode<S:Encoder>(s: &S) {
            s.emit_rec(|| {
                s.emit_field("node", 0, || self.node.encode(s));
                s.emit_field("span", 1, || self.span.encode(s));
            })
        }
    }

    impl<
        D: Decoder,
        T: Decodable<D>
    > spanned<T>: Decodable<D> {
        fn decode(d: &D) -> spanned<T> {
            d.read_rec(|| {
                {
                    node: d.read_field("node".to_string(), 0, || decode(d)),
                    span: d.read_field("span".to_string(), 1, || decode(d)),
                }
            })
        }
    }

Functions

expand_deriving_encodable