Expand description

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

For example, a type like:

#[derive(RustcEncodable, RustcDecodable)]
struct Node { id: usize }

would generate two implementations like:

impl<S: Encoder<E>, E> Encodable<S, E> for Node {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_struct("Node", 1, |this| {
            this.emit_struct_field("id", 0, |this| {
                Encodable::encode(&self.id, this)
                /* this.emit_usize(self.id) can also be used */
            })
        })
    }
}

impl<D: Decoder<E>, E> Decodable<D, E> for Node {
    fn decode(d: &mut D) -> Result<Node, E> {
        d.read_struct("Node", 1, |this| {
            match this.read_struct_field("id", 0, |this| Decodable::decode(this)) {
                Ok(id) => Ok(Node { id: id }),
                Err(e) => Err(e),
            }
        })
    }
}

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

#[derive(RustcEncodable, RustcDecodable)]
struct Spanned<T> { node: T, span: Span }

would yield functions like:

impl<
    S: Encoder<E>,
    E,
    T: Encodable<S, E>
> Encodable<S, E> for Spanned<T> {
    fn encode(&self, s: &mut S) -> Result<(), E> {
        s.emit_struct("Spanned", 2, |this| {
            this.emit_struct_field("node", 0, |this| self.node.encode(this))
                .unwrap();
            this.emit_struct_field("span", 1, |this| self.span.encode(this))
        })
    }
}

impl<
    D: Decoder<E>,
    E,
    T: Decodable<D, E>
> Decodable<D, E> for Spanned<T> {
    fn decode(d: &mut D) -> Result<Spanned<T>, E> {
        d.read_struct("Spanned", 2, |this| {
            Ok(Spanned {
                node: this.read_struct_field("node", 0, |this| Decodable::decode(this))
                    .unwrap(),
                span: this.read_struct_field("span", 1, |this| Decodable::decode(this))
                    .unwrap(),
            })
        })
    }
}

Functions