json-codec 0.1.0

JSON Codec implementation
Documentation
#[macro_export]
/// Macro to support declarative decoding into struct types.
///
/// # Syntax:
///
/// ```text
/// object! {
///     'let' 'decoder' '=' decoder_var_name ';'
///     'let' 'buffer'  '=' mutable_reference_to_utf8_buffer ';' // optional
///     struct_type '{'
///         ( field_name ':' ('req' / 'opt') '.' field_string '=>' expression ',' )+
///     '}'
/// }
/// ```
///
/// # Example:
///
/// ```text
/// struct Point {
///     x: u32,
///     y: u32
/// }
///
/// object! {
///     let decoder = d;
///     Point {
///         x: req. "x" => Decoder::u32,
///         y: req. "y" => Decoder::u32
///     }
/// }
/// ```
macro_rules! object {
    (
      let decoder = $dec:ident;
      let buffer  = $buf:expr;
      $T:ident {
          $($name:ident: $modus:ident. $key:expr => $action:expr),+
      }
    ) => {{
        $dec.object1(|$dec| {
            $(let mut $name = None;)+
            loop {
                $buf.reset();
                try!($dec.key_str($buf, false));
                match $buf.as_str() {
                    $($key => {
                        let v = try!($dec.value($action));
                        $name = Some(v.value);
                        if v.is_last {
                            break
                        }
                    })+
                    _ => {
                        let v = try!($dec.value(Decoder::skip));
                        if v.is_last {
                            break
                        }
                    }
                }
            }
            Ok($T {
                $($name: to_field!($key, $name, $modus),)+
            })
        })
    }};
    (
      let decoder = $dec:ident;
      $T:ident {
          $($name:ident: $modus:ident. $key:expr => $action:expr),+
      }
    ) => {{
        $dec.object1(|$dec| {
            $(let mut $name = None;)+
            loop {
                match try!($dec.key()).as_ref() {
                    $($key => {
                        let v = try!($dec.value($action));
                        $name = Some(v.value);
                        if v.is_last {
                            break
                        }
                    })+
                    _ => {
                        let v = try!($dec.value(Decoder::skip));
                        if v.is_last {
                            break
                        }
                    }
                }
            }
            Ok($T {
                $($name: to_field!($key, $name, $modus),)+
            })
        })
    }}
}

#[macro_export]
macro_rules! to_field {
    ($msg:expr, $e:expr, opt) => {
        match $e {
            Some(e) => e,
            None    => None
        }
    };
    ($msg:expr, $e:expr, req) => {
        match $e {
            Some(e) => e,
            None    => return Err(DecodeError::Expected($msg))
        }
    }
}

#[macro_export]
/// Macro to support declarative decoding into `Vec`.
///
/// This only supports homogenous JSON arrays. To decode
/// arrays with different element types use `Decoder::array`.
///
/// # Syntax
///
/// ```text
/// array!(decoder_var_name ',' expression) /
/// array!(expression)
/// ```
/// Two variants are supported, one with an explicit decoder
/// variable and the other one without. If not given, a lambda
/// function will be generated which needs to be supplied to a
/// decoder and is best used inside `object!` macro invications.
macro_rules! array {
    ($dec:ident, $e:expr) => {{
        let mut v = Vec::new();
        for x in try!($dec.array_iter($e)) {
            v.push(try!(x))
        }
        Ok(v)
    }};
    ($e:expr) => {{ |dec| {
        let mut v = Vec::new();
        for x in try!(dec.array_iter($e)) {
            v.push(try!(x))
        }
        Ok(v)
    }}}
}