#[macro_export]
macro_rules! extract {
(
let decoder = $dec: ident;
let buffer = $buf: expr;
$($name: ident: $modus: ident. $typ: ty = $key: expr => $action: expr),+
) => {{
struct X {
$($name: $typ),+
}
object! {
let decoder = $dec;
let buffer = &mut $buf;
X {
$($name: $modus. $key => $action),+
}
}
}};
(
let decoder = $dec: ident;
$($name: ident: $modus: ident. $typ: ty = $key: expr => $action: expr),+
) => {{
struct X {
$($name: $typ),+
}
object! {
let decoder = $dec;
X {
$($name: $modus. $key => $action),+
}
}
}};
}
#[macro_export]
macro_rules! object {
(
let decoder = $dec: ident;
let buffer = $buf: expr;
$T: ident {
$($name: ident: $modus: ident. $key: expr => $action: expr),+
}
) => {{
$dec.object().and_then(|()| {
$(let mut $name = None;)+
while $dec.has_more()? {
$buf.reset();
$dec.key_str($buf, false)?;
match $buf.as_str() {
$($key => { $name = Some($action?) })+
_ => { $dec.skip()? }
}
}
Ok($T {
$($name: to_field!($key, $name, $modus),)+
})
})
}};
(
let decoder = $dec: ident;
$T: ident {
$($name: ident: $modus: ident. $key: expr => $action: expr),+
}
) => {{
$dec.object().and_then(|()| {
$(let mut $name = None;)+
while $dec.has_more()? {
match $dec.key()?.as_ref() {
$($key => { $name = Some($action?) })+
_ => { $dec.skip()? }
}
}
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($crate::DecodeError::Expected($msg))
}
}
}
#[macro_export]
macro_rules! array {
($dec: ident, $action: expr) => {{
$dec.array().and_then(|()| {
let mut v = Vec::new();
while $dec.has_more()? {
v.push($action?)
}
Ok(v)
})
}}
}