pub trait Visitor<'a, Err> {
// Provided methods
fn visit_simple(&mut self, item: TaggedItem<'a>) -> Result<(), Err> { ... }
fn visit_array_begin(
&mut self,
array: TaggedItem<'a>,
size: Option<u64>,
) -> Result<bool, Err> { ... }
fn visit_array_index(
&mut self,
array: TaggedItem<'a>,
index: u64,
) -> Result<bool, Err> { ... }
fn visit_array_end(&mut self, array: TaggedItem<'a>) -> Result<(), Err> { ... }
fn visit_dict_begin(
&mut self,
dict: TaggedItem<'a>,
size: Option<u64>,
) -> Result<bool, Err> { ... }
fn visit_dict_key(
&mut self,
dict: TaggedItem<'a>,
key: TaggedItem<'a>,
is_first: bool,
) -> Result<bool, Err> { ... }
fn visit_dict_end(&mut self, dict: TaggedItem<'a>) -> Result<(), Err> { ... }
}Expand description
Visitor for the structure of a CBOR item.
The visit is guided by the visitor in the sense that uninteresting arrays, dicts,
or some of their values can be skipped by returning false from the respective
methods.
Note the different lifetimes needed on the impl Visitor! The first lifetime
'a describes how long the underlying Cbor value lives, i.e. how long the items
passed into the visitor’s methods stay available. The second lifetime 'b denotes
the mutable borrow of the String we’re writing into, which needs to be more
short-lived since we want to move the String before the Cbor expires.
Example:
use std::fmt::{Error, Formatter, Write};
use cbor_data::{Cbor, CborOwned, TaggedItem, Visitor};
fn pretty_print(value: &Cbor) -> Result<String, Error> {
struct X<'a>(&'a mut String);
impl<'a, 'b> Visitor<'a, Error> for X<'b> {
fn visit_simple(&mut self, item: TaggedItem<'a>) -> Result<(), Error> {
write!(self.0, "{}", item)
}
fn visit_array_begin(&mut self, item: TaggedItem<'a>, size: Option<u64>) -> Result<bool, Error> {
write!(self.0, "[")?;
Ok(true)
}
fn visit_array_index(&mut self, item: TaggedItem<'a>, idx: u64) -> Result<bool, Error> {
if idx > 0 {
write!(self.0, ", ")?;
}
Ok(true)
}
fn visit_array_end(&mut self, item: TaggedItem<'a>) -> Result<(), Error> {
write!(self.0, "]")
}
fn visit_dict_begin(&mut self, item: TaggedItem<'a>, size: Option<u64>) -> Result<bool, Error> {
write!(self.0, "{{")?;
Ok(true)
}
fn visit_dict_key(&mut self, item: TaggedItem<'a>, key: TaggedItem<'a>, is_first: bool) -> Result<bool, Error> {
if !is_first {
write!(self.0, ", ")?;
}
write!(self.0, "{}: ", key)?;
Ok(true)
}
fn visit_dict_end(&mut self, item: TaggedItem<'a>) -> Result<(), Error> {
write!(self.0, "}}")
}
}
let mut s = String::new();
value.visit(&mut X(&mut s))?;
Ok(s)
}
let bytes = vec![
0xc4u8, 0x84, 5, 0xa2, 0x61, b'a', 0x39, 2, 154, 0x61, b'b', 0x46, b'd', b'e', b'f', b'd',
b'e', b'f', 0x82, 0xf4, 0x65, b'h', b'e', b'l', b'l', b'o', 0xd9, 48, 57, 0xf6,
];
let cbor = CborOwned::canonical(bytes).expect("invalid CBOR");
let pretty = pretty_print(cbor.as_ref()).expect("should always be able to write to a String …");
assert_eq!(pretty, r#"[5, {"a": -667, "b": h'646566646566'}, [false, "hello"], 12345(null)]"#);Provided Methods§
Sourcefn visit_simple(&mut self, item: TaggedItem<'a>) -> Result<(), Err>
fn visit_simple(&mut self, item: TaggedItem<'a>) -> Result<(), Err>
Visit a simple item, i.e. item.kind will neither be Array nor Dict.
Sourcefn visit_array_begin(
&mut self,
array: TaggedItem<'a>,
size: Option<u64>,
) -> Result<bool, Err>
fn visit_array_begin( &mut self, array: TaggedItem<'a>, size: Option<u64>, ) -> Result<bool, Err>
Visit the beginning of an array. size is None for indefinite size encoding.
Return false to skip this array, meaning that visit_array_index
will NOT be called for it.
Sourcefn visit_array_index(
&mut self,
array: TaggedItem<'a>,
index: u64,
) -> Result<bool, Err>
fn visit_array_index( &mut self, array: TaggedItem<'a>, index: u64, ) -> Result<bool, Err>
Visit an array element at the given index. Return false to skip over the element’s
contents, otherwise nested items (simple or otherwise) will be visited before visiting
the next element or the array’s end.
Sourcefn visit_array_end(&mut self, array: TaggedItem<'a>) -> Result<(), Err>
fn visit_array_end(&mut self, array: TaggedItem<'a>) -> Result<(), Err>
Visit the end of the current array.
Sourcefn visit_dict_begin(
&mut self,
dict: TaggedItem<'a>,
size: Option<u64>,
) -> Result<bool, Err>
fn visit_dict_begin( &mut self, dict: TaggedItem<'a>, size: Option<u64>, ) -> Result<bool, Err>
Visit the beginning of an dict. size is None for indefinite size encoding.
Return false to skip this dict, meaning that visit_dict_key
will NOT be called for it.
Sourcefn visit_dict_key(
&mut self,
dict: TaggedItem<'a>,
key: TaggedItem<'a>,
is_first: bool,
) -> Result<bool, Err>
fn visit_dict_key( &mut self, dict: TaggedItem<'a>, key: TaggedItem<'a>, is_first: bool, ) -> Result<bool, Err>
Visit a dict value at the given key. Return false to skip over the value’s
contents, otherwise nested items (simple or otherwise) will be visited before visiting
the next key or the dict’s end.
In most cases the key will be a string or an integer. In the rare case where a key is a complex struct, you can visit it manually.
Sourcefn visit_dict_end(&mut self, dict: TaggedItem<'a>) -> Result<(), Err>
fn visit_dict_end(&mut self, dict: TaggedItem<'a>) -> Result<(), Err>
Visit the end of the current dict.