use crate::de::Error; /// Deserializes table values into enum variants. pub(crate) struct TableEnumDeserializer { value: crate::Item, } impl TableEnumDeserializer { pub(crate) fn new(value: crate::Item) -> Self { TableEnumDeserializer { value } } } impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer { type Error = Error; fn unit_variant(self) -> Result<(), Self::Error> { match self.value { crate::Item::Table(values) => { if values.is_empty() { Ok(()) } else { Err(Error::custom("expected empty table", values.span())) } } crate::Item::Value(crate::Value::InlineTable(values)) => { if values.is_empty() { Ok(()) } else { Err(Error::custom("expected empty table", values.span())) } } e => Err(Error::custom( format!("expected table, found {}", e.type_name()), e.span(), )), } } fn newtype_variant_seed(self, seed: T) -> Result where T: serde::de::DeserializeSeed<'de>, { seed.deserialize(super::ValueDeserializer::new(self.value)) } fn tuple_variant(self, len: usize, visitor: V) -> Result where V: serde::de::Visitor<'de>, { match self.value { crate::Item::Table(values) => { let values_span = values.span(); let tuple_values = values .items .into_iter() .enumerate() .map( |(index, (_, value))| match value.key.get().parse::() { Ok(key_index) if key_index == index => Ok(value.value), Ok(_) | Err(_) => Err(Error::custom( format!( "expected table key `{}`, but was `{}`", index, value.key.get() ), value.key.span(), )), }, ) // Fold all values into a `Vec`, or return the first error. .fold(Ok(Vec::with_capacity(len)), |result, value_result| { result.and_then(move |mut tuple_values| match value_result { Ok(value) => { tuple_values.push(value); Ok(tuple_values) } // `Result` to `Result, Self::Error>` Err(e) => Err(e), }) })?; if tuple_values.len() == len { serde::de::Deserializer::deserialize_seq( super::ArrayDeserializer::new(tuple_values, values_span), visitor, ) } else { Err(Error::custom( format!("expected tuple with length {}", len), values_span, )) } } crate::Item::Value(crate::Value::InlineTable(values)) => { let values_span = values.span(); let tuple_values = values .items .into_iter() .enumerate() .map( |(index, (_, value))| match value.key.get().parse::() { Ok(key_index) if key_index == index => Ok(value.value), Ok(_) | Err(_) => Err(Error::custom( format!( "expected table key `{}`, but was `{}`", index, value.key.get() ), value.key.span(), )), }, ) // Fold all values into a `Vec`, or return the first error. .fold(Ok(Vec::with_capacity(len)), |result, value_result| { result.and_then(move |mut tuple_values| match value_result { Ok(value) => { tuple_values.push(value); Ok(tuple_values) } // `Result` to `Result, Self::Error>` Err(e) => Err(e), }) })?; if tuple_values.len() == len { serde::de::Deserializer::deserialize_seq( super::ArrayDeserializer::new(tuple_values, values_span), visitor, ) } else { Err(Error::custom( format!("expected tuple with length {}", len), values_span, )) } } e => Err(Error::custom( format!("expected table, found {}", e.type_name()), e.span(), )), } } fn struct_variant( self, fields: &'static [&'static str], visitor: V, ) -> Result where V: serde::de::Visitor<'de>, { serde::de::Deserializer::deserialize_struct( super::ValueDeserializer::new(self.value).with_struct_key_validation(), "", // TODO: this should be the variant name fields, visitor, ) } }