reikland 0.1.3

A serde-compatible Ruby marshal parser and deserializer
Documentation
use serde_core::de::{DeserializeSeed, MapAccess, Visitor};

use super::{Deserializer, ErrorKind, MarshalDeserializeError, rb_str_to_str};
use crate::{
    cursor::{object_table::ObjectIdx, symbol_table::SymbolIdx},
    marshal::MarshalData,
};
pub(crate) struct MapDeserializer<'a, 'b> {
    data: &'b MarshalData<'a>,
    iter: std::slice::Iter<'b, (ObjectIdx, ObjectIdx)>,
    value_idx: Option<ObjectIdx>,
}

impl<'a, 'b> MapDeserializer<'a, 'b> {
    pub(crate) fn new(data: &'b MarshalData<'a>, pairs: &'b [(ObjectIdx, ObjectIdx)]) -> Self {
        MapDeserializer {
            data,
            iter: pairs.iter(),
            value_idx: None,
        }
    }
}

impl<'de, 'b> MapAccess<'de> for MapDeserializer<'de, 'b> {
    type Error = MarshalDeserializeError;

    fn next_key_seed<K: DeserializeSeed<'de>>(
        &mut self,
        seed: K,
    ) -> Result<Option<K::Value>, MarshalDeserializeError> {
        match self.iter.next() {
            Some(&(key_idx, val_idx)) => {
                self.value_idx = Some(val_idx);
                let de = Deserializer {
                    data: self.data,
                    idx: key_idx,
                };
                seed.deserialize(de).map(Some)
            }
            None => Ok(None),
        }
    }

    fn next_value_seed<V: DeserializeSeed<'de>>(
        &mut self,
        seed: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        let idx = self
            .value_idx
            .take()
            .expect("next_value_seed called before next_key_seed");
        let de = Deserializer {
            data: self.data,
            idx,
        };
        seed.deserialize(de)
    }

    fn size_hint(&self) -> Option<usize> {
        Some(self.iter.len())
    }
}

pub(crate) struct IvarMapDeserializer<'a, 'b> {
    data: &'b MarshalData<'a>,
    iter: std::slice::Iter<'b, (SymbolIdx, ObjectIdx)>,
    value_idx: Option<ObjectIdx>,
}

impl<'a, 'b> IvarMapDeserializer<'a, 'b> {
    pub(crate) fn new(data: &'b MarshalData<'a>, ivars: &'b [(SymbolIdx, ObjectIdx)]) -> Self {
        IvarMapDeserializer {
            data,
            iter: ivars.iter(),
            value_idx: None,
        }
    }
}

impl<'de, 'b> MapAccess<'de> for IvarMapDeserializer<'de, 'b> {
    type Error = MarshalDeserializeError;

    fn next_key_seed<K: DeserializeSeed<'de>>(
        &mut self,
        seed: K,
    ) -> Result<Option<K::Value>, MarshalDeserializeError> {
        match self.iter.next() {
            Some(&(sym_idx, val_idx)) => {
                self.value_idx = Some(val_idx);
                let rb = self
                    .data
                    .symbol(sym_idx)
                    .ok_or(ErrorKind::InvalidSymbolIndex(sym_idx.inner()))?;
                let s = rb_str_to_str(rb)?;
                seed.deserialize(serde_core::de::value::BorrowedStrDeserializer::new(s))
                    .map(Some)
            }
            None => Ok(None),
        }
    }

    fn next_value_seed<V: DeserializeSeed<'de>>(
        &mut self,
        seed: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        let idx = self
            .value_idx
            .take()
            .expect("next_value_seed called before next_key_seed");
        let de = Deserializer {
            data: self.data,
            idx,
        };
        seed.deserialize(de)
    }

    fn size_hint(&self) -> Option<usize> {
        Some(self.iter.len())
    }
}

pub(crate) struct SymbolNameDeserializer<'de> {
    pub(crate) name: &'de str,
}

impl<'de> serde_core::de::Deserializer<'de> for SymbolNameDeserializer<'de> {
    type Error = MarshalDeserializeError;

    fn deserialize_any<V: Visitor<'de>>(
        self,
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        visitor.visit_borrowed_str(self.name)
    }

    fn deserialize_str<V: Visitor<'de>>(
        self,
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        self.deserialize_any(visitor)
    }

    fn deserialize_string<V: Visitor<'de>>(
        self,
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        self.deserialize_any(visitor)
    }

    fn deserialize_ignored_any<V: Visitor<'de>>(
        self,
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        visitor.visit_unit()
    }

    fn deserialize_unit<V: Visitor<'de>>(
        self,
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        visitor.visit_unit()
    }

    fn deserialize_unit_struct<V: Visitor<'de>>(
        self,
        _name: &'static str,
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        visitor.visit_unit()
    }

    serde_core::forward_to_deserialize_any! {
        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char
        bytes byte_buf option newtype_struct seq tuple tuple_struct map struct enum identifier
    }
}

pub(crate) struct IvarsDeserializer<'a, 'b> {
    pub(crate) data: &'b MarshalData<'a>,
    pub(crate) ivars: &'b [(SymbolIdx, ObjectIdx)],
}

impl<'de, 'b> serde_core::de::Deserializer<'de> for IvarsDeserializer<'de, 'b> {
    type Error = MarshalDeserializeError;

    fn deserialize_any<V: Visitor<'de>>(
        self,
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        visitor.visit_map(IvarMapDeserializer::new(self.data, self.ivars))
    }

    fn deserialize_map<V: Visitor<'de>>(
        self,
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        self.deserialize_any(visitor)
    }

    fn deserialize_struct<V: Visitor<'de>>(
        self,
        _name: &'static str,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        self.deserialize_any(visitor)
    }

    fn deserialize_ignored_any<V: Visitor<'de>>(
        self,
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        visitor.visit_unit()
    }

    fn deserialize_unit<V: Visitor<'de>>(
        self,
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        visitor.visit_unit()
    }

    fn deserialize_unit_struct<V: Visitor<'de>>(
        self,
        _name: &'static str,
        visitor: V,
    ) -> Result<V::Value, MarshalDeserializeError> {
        visitor.visit_unit()
    }

    serde_core::forward_to_deserialize_any! {
        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
        bytes byte_buf option newtype_struct seq tuple tuple_struct enum identifier
    }
}