macro_rules! enc_try {
($result:expr, $offset:expr) => { ... };
($result:expr) => { ... };
($buf:expr, $offset:expr; $fun:expr) => { ... };
($buf:expr, $offset:expr; $fun:expr, $($args:expr),+) => { ... };
($buf:expr, $offset:expr; $object:expr; $fun:ident) => { ... };
($buf:expr, $offset:expr; $object:expr; $fun:ident, $($args:expr),+) => { ... };
($buf:expr; $($tts:tt)+) => { ... };
}
Expand description
Extracts the result of encoding/decoding (the new offset and the output) only if no errors were encountered in encoding.
This macro makes it possible to handle offsets easily for the following use cases:
enc_try!(result, offset)
: Unwrap an already-provided result that
represents starting from offset
in the buffer.
enc_try!(buf, offset; encoder, args..)
: Use the encoder function, called with the
optionally provided arguments, on the buffer starting from offset
.
enc_try!(buf, offset; object; method, args..)
: Same as the above, but the
encoder function is a member method of object.
Additionally, the offset can always be omitted from any of the above, which would result in it defaulting to 0. Idiomatically, the way to combine encoders is to define another encoder as follows:
// call a simple encoder
let (bytes, out1) = enc_try!(buf; encoder1);
/* Do something with out1 */
// call another encoder, but starting at the previous offset
let (bytes, out2) = enc_try!(buf, bytes; encoder2);
/* Note that bytes is shadowed. Alternatively you could mutably update a
variable. */
// subsequently, encode a struct into the buffer, with some extra arguments
let (bytes, out3) = enc_try!(buf, bytes; someheader; encode, 2, 5);
// report success without returning a meaningful output
stream_done!(bytes);
Then, using an encoder can be done simply by:
match encoder(&mut buf) {
SResult::Done(off, out) => { /* celebrate */ }
SResult::Needed(off) => { /* get more memory? */ }
SResult::Error(err) => { /* give up */ }
}