serde_magnus 0.1.1

Serde integration for Magnus
Documentation
use super::{ArrayDeserializer, Deserializer, HashDeserializer};
use crate::error::Error;
use magnus::{RArray, RHash, Value};
use serde::de::{DeserializeSeed, Unexpected, VariantAccess};

pub struct VariantDeserializer {
    value: Value,
}

impl VariantDeserializer {
    pub fn new(value: Value) -> VariantDeserializer {
        VariantDeserializer { value }
    }
}

impl<'i> VariantAccess<'i> for VariantDeserializer {
    type Error = Error;

    fn unit_variant(self) -> Result<(), Self::Error> {
        if self.value.is_nil() {
            Ok(())
        } else {
            Err(serde::de::Error::invalid_type(
                #[allow(clippy::unnecessary_to_owned)]
                Unexpected::Other(&unsafe { self.value.classname() }.into_owned()),
                &"unit variant",
            ))
        }
    }

    fn newtype_variant_seed<Seed>(self, seed: Seed) -> Result<Seed::Value, Self::Error>
    where
        Seed: DeserializeSeed<'i>,
    {
        seed.deserialize(Deserializer::new(self.value))
    }

    fn tuple_variant<Visitor>(
        self,
        _len: usize,
        visitor: Visitor,
    ) -> Result<Visitor::Value, Self::Error>
    where
        Visitor: serde::de::Visitor<'i>,
    {
        if let Some(array) = RArray::from_value(self.value) {
            visitor.visit_seq(&mut ArrayDeserializer::new(array))
        } else {
            Err(serde::de::Error::invalid_type(
                #[allow(clippy::unnecessary_to_owned)]
                Unexpected::Other(&unsafe { self.value.classname() }.into_owned()),
                &"tuple variant",
            ))
        }
    }

    fn struct_variant<Visitor>(
        self,
        _fields: &'static [&'static str],
        visitor: Visitor,
    ) -> Result<Visitor::Value, Self::Error>
    where
        Visitor: serde::de::Visitor<'i>,
    {
        if let Some(hash) = RHash::from_value(self.value) {
            visitor.visit_map(&mut HashDeserializer::new(hash)?)
        } else {
            Err(serde::de::Error::invalid_type(
                #[allow(clippy::unnecessary_to_owned)]
                Unexpected::Other(&unsafe { self.value.classname() }.into_owned()),
                &"struct variant",
            ))
        }
    }
}