// Copyright (C) 2018 Sebastian Dröge // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use serde::de; use serde::de::{Deserialize, Deserializer, EnumAccess, SeqAccess, VariantAccess, Visitor}; use serde::ser::{Serialize, SerializeSeq, Serializer}; use std::fmt; use CapsFeatures; use CapsFeaturesRef; enum CapsFeaturesVariantKinds { Any, Some, } const CAPS_FEATURES_VARIANT_ANY_ID: u32 = 0; const CAPS_FEATURES_VARIANT_ANY_STR: &str = "Any"; const CAPS_FEATURES_VARIANT_SOME_ID: u32 = 1; const CAPS_FEATURES_VARIANT_SOME_STR: &str = "Some"; const CAPS_FEATURES_VARIANT_NAMES: &[&str] = &[ &CAPS_FEATURES_VARIANT_ANY_STR, &CAPS_FEATURES_VARIANT_SOME_STR, ]; struct CapsFeaturesForIterSe<'a>(&'a CapsFeaturesRef); impl<'a> Serialize for CapsFeaturesForIterSe<'a> { fn serialize(&self, serializer: S) -> Result { let iter = self.0.iter(); let size = iter.size_hint().0; if size > 0 { let mut seq = serializer.serialize_seq(Some(size))?; for feature in iter { seq.serialize_element(feature)?; } seq.end() } else { let seq = serializer.serialize_seq(None)?; seq.end() } } } impl Serialize for CapsFeaturesRef { fn serialize(&self, serializer: S) -> Result { if self.is_any() { serializer.serialize_unit_variant( stringify!(CapsFeatures), CAPS_FEATURES_VARIANT_ANY_ID, CAPS_FEATURES_VARIANT_ANY_STR, ) } else { serializer.serialize_newtype_variant( stringify!(CapsFeatures), CAPS_FEATURES_VARIANT_SOME_ID, CAPS_FEATURES_VARIANT_SOME_STR, &CapsFeaturesForIterSe(&self), ) } } } impl Serialize for CapsFeatures { fn serialize(&self, serializer: S) -> Result { self.as_ref().serialize(serializer) } } struct CapsFeaturesSome(CapsFeatures); struct CapsFeaturesSomeVisitor; impl<'de> Visitor<'de> for CapsFeaturesSomeVisitor { type Value = CapsFeaturesSome; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a sequence of `&str`") } fn visit_seq>(self, mut seq: A) -> Result { let mut features = CapsFeatures::new_empty(); while let Some(feature) = seq.next_element::()? { features.add(feature.as_ref()); } Ok(CapsFeaturesSome(features)) } } impl<'de> Deserialize<'de> for CapsFeaturesSome { fn deserialize>(deserializer: D) -> Result { deserializer.deserialize_seq(CapsFeaturesSomeVisitor) } } struct CapsFeaturesVariantKindsVisitor; impl<'de> Visitor<'de> for CapsFeaturesVariantKindsVisitor { type Value = CapsFeaturesVariantKinds; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a Caps variant kind (`Any` or `Some`)") } fn visit_u32(self, value: u32) -> Result { match value { CAPS_FEATURES_VARIANT_ANY_ID => Ok(CapsFeaturesVariantKinds::Any), CAPS_FEATURES_VARIANT_SOME_ID => Ok(CapsFeaturesVariantKinds::Some), _ => Err(de::Error::invalid_value( de::Unexpected::Unsigned(value as u64), &self, )), } } fn visit_str(self, value: &str) -> Result { match value { CAPS_FEATURES_VARIANT_ANY_STR => Ok(CapsFeaturesVariantKinds::Any), CAPS_FEATURES_VARIANT_SOME_STR => Ok(CapsFeaturesVariantKinds::Some), _ => Err(de::Error::unknown_variant( value, CAPS_FEATURES_VARIANT_NAMES, )), } } } impl<'de> Deserialize<'de> for CapsFeaturesVariantKinds { fn deserialize>(deserializer: D) -> Result { deserializer.deserialize_identifier(CapsFeaturesVariantKindsVisitor) } } struct CapsFeaturesVisitor; impl<'de> Visitor<'de> for CapsFeaturesVisitor { type Value = CapsFeatures; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a CapsFeatures enum (`Any` or `Some()`)") } fn visit_enum>(self, data: A) -> Result { let res = match data.variant()? { (CapsFeaturesVariantKinds::Any, _v) => CapsFeatures::new_any(), (CapsFeaturesVariantKinds::Some, v) => v .newtype_variant::() .map(|caps_features_some| caps_features_some.0)?, }; Ok(res) } } impl<'de> Deserialize<'de> for CapsFeatures { fn deserialize>(deserializer: D) -> Result { deserializer.deserialize_enum( stringify!(Caps), CAPS_FEATURES_VARIANT_NAMES, CapsFeaturesVisitor, ) } }