Skip to content

Instantly share code, notes, and snippets.

@willemolding
Created October 19, 2021 00:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save willemolding/f2c48fc88059fe0d20b491c6bad4883d to your computer and use it in GitHub Desktop.
Save willemolding/f2c48fc88059fe0d20b491c6bad4883d to your computer and use it in GitHub Desktop.
impl<'de, 'a, R: Read> de::Deserializer<'de> for &'a mut Deserializer<R> {
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
match self.layout_iter.next() {
Some(rule) => {
match rule {
BinProtRule::Unit => {
self.rdr.bin_read_unit()?;
visitor.visit_unit()
}
BinProtRule::Record(fields) => {
visitor.visit_map(MapAccess::new(
self,
fields.into_iter().map(|f| f.field_name).rev().collect(),
))
}
BinProtRule::Tuple(items) => {
visitor.visit_seq(SeqAccess::new(self, items.len()))
}
BinProtRule::Bool => visitor.visit_bool(self.rdr.bin_read_bool()?),
BinProtRule::Sum(summands) => {
// read the enum variant index.
// We need this to select which variant layout to use
// when deserializing the variants data
let index = self.rdr.bin_read_variant_index()?;
let variant_rules = summands[index as usize].ctor_args.clone();
self.layout_iter.push(vec![BinProtRule::Tuple(variant_rules)]);
visitor
.visit_enum(ValueEnum::new(self, summands[index as usize].clone()))
}
BinProtRule::Option(some_rule) => {
let index = self.rdr.bin_read_variant_index()?; // 0 or 1
match index {
0 => visitor.visit_none(),
1 => {
self.layout_iter.push(vec![*some_rule]);
visitor.visit_some(self)
}
_ => Err(Error::InvalidOptionByte { got: index }),
}
}
BinProtRule::String => visitor.visit_bytes(&self.rdr.bin_read_bytes()?),
BinProtRule::Float => {
visitor.visit_f64(self.rdr.read_f64::<LittleEndian>()?)
}
BinProtRule::Char => {
let c = self.rdr.read_u8()?;
visitor.visit_char(c as char)
}
BinProtRule::List(element_rule) => {
// read the length
let len = self.rdr.bin_read_nat0()?;
// request the iterator repeats the list elements the current number of times
self.layout_iter.push_n(*element_rule, len);
// read the elements
visitor.visit_seq(SeqAccess::new_list(self, len))
}
BinProtRule::Int
| BinProtRule::Int32
| BinProtRule::Int64
| BinProtRule::NativeInt => visitor.visit_i64(self.rdr.bin_read_integer()?),
// SNIP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment