diff --git a/Cargo.toml b/Cargo.toml index cd3bc2a..43dd9ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,11 +8,9 @@ edition = "2021" repository = "https://github.com/pykeio/ssml" [dependencies] -dyn-clone = "1.0" serde = { version = "1.0", optional = true, default-features = false, features = [ "alloc", "derive" ] } -erased-serde = { version = "0.4", optional = true, default-features = false, features = [ "alloc" ] } [features] default = [ "std" ] std = [] -serde = [ "dep:serde", "dep:erased-serde" ] +serde = [ "dep:serde" ] diff --git a/src/element.rs b/src/element.rs index 7be5d4e..f75d04f 100644 --- a/src/element.rs +++ b/src/element.rs @@ -1,9 +1,7 @@ -use alloc::{borrow::Cow, boxed::Box, vec::Vec}; +use alloc::{borrow::Cow, string::ToString, vec::Vec}; use core::fmt::{Debug, Write}; -use dyn_clone::DynClone; - -use crate::{Audio, Break, Emphasis, Mark, Meta, Serialize, SerializeOptions, Text, Voice, XmlWriter}; +use crate::{Audio, Break, Emphasis, Mark, Meta, Serialize, SerializeOptions, Text, Voice, XmlWriter, util}; macro_rules! el { ( @@ -43,7 +41,7 @@ pub(crate) use el; el! { /// Represents all SSML elements. #[derive(Clone, Debug)] - #[cfg_attr(feature = "serde", derive(serde::Serialize))] + #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[non_exhaustive] pub enum Element<'s> { Text(Text<'s>), @@ -54,9 +52,7 @@ el! { Emphasis(Emphasis<'s>), Mark(Mark<'s>), FlavorMSTTS(crate::mstts::Element<'s>), - /// A dyn element can be used to implement your own custom elements outside of the `ssml` crate. See - /// [`DynElement`] for more information and examples. - Dyn(Box) + Custom(CustomElement<'s>) // Lang(LangElement), // Paragraph(ParagraphElement), // Phoneme(PhonemeElement), @@ -82,254 +78,88 @@ impl<'s> Element<'s> { Self::Break(el) => Element::Break(el), Self::Emphasis(el) => Element::Emphasis(el.into_owned()), Self::Mark(el) => Element::Mark(el.into_owned()), + Self::Custom(el) => Element::Custom(el.into_owned()), _ => panic!() } } } -#[cfg(feature = "serde")] -impl<'s, 'a> serde::Deserialize<'a> for Element<'s> { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'a> - { - use alloc::string::String; - use core::{fmt, marker::PhantomData}; - - #[allow(non_camel_case_types)] - enum ElementField { - Text, - Audio, - Voice, - Meta, - Break, - Emphasis, - Mark - } - - struct ElementFieldVisitor; - - impl<'de> serde::de::Visitor<'de> for ElementFieldVisitor { - type Value = ElementField; - - fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("variant identifier") - } - - fn visit_u64<__E>(self, val: u64) -> serde::__private::Result - where - __E: serde::de::Error - { - match val { - 0u64 => Ok(ElementField::Text), - 1u64 => Ok(ElementField::Audio), - 2u64 => Ok(ElementField::Voice), - 3u64 => Ok(ElementField::Meta), - 4u64 => Ok(ElementField::Break), - 5u64 => Ok(ElementField::Emphasis), - 6u64 => Ok(ElementField::Mark), - 7u64 => Err(serde::de::Error::custom("DynElements cannot be deserialized")), - _ => Err(serde::de::Error::invalid_value(serde::de::Unexpected::Unsigned(val), &"variant index 0 <= i < 8")) - } - } - - fn visit_str(self, val: &str) -> Result - where - E: serde::de::Error - { - match val { - "Text" => Ok(ElementField::Text), - "Audio" => Ok(ElementField::Audio), - "Voice" => Ok(ElementField::Voice), - "Meta" => Ok(ElementField::Meta), - "Break" => Ok(ElementField::Break), - "Emphasis" => Ok(ElementField::Emphasis), - "Mark" => Ok(ElementField::Mark), - "Dyn" => Err(serde::de::Error::custom("DynElements cannot be deserialized")), - _ => Err(serde::de::Error::unknown_variant(val, VARIANTS)) - } - } - - fn visit_bytes(self, val: &[u8]) -> serde::__private::Result - where - E: serde::de::Error - { - match val { - b"Text" => Ok(ElementField::Text), - b"Audio" => Ok(ElementField::Audio), - b"Voice" => Ok(ElementField::Voice), - b"Meta" => Ok(ElementField::Meta), - b"Break" => Ok(ElementField::Break), - b"Emphasis" => Ok(ElementField::Emphasis), - b"Mark" => Ok(ElementField::Mark), - b"Dyn" => Err(serde::de::Error::custom("DynElements cannot be deserialized")), - _ => { - let __value = &String::from_utf8_lossy(val); - Err(serde::de::Error::unknown_variant(__value, VARIANTS)) - } - } - } - } - - impl<'de> serde::Deserialize<'de> for ElementField { - #[inline] - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de> - { - serde::Deserializer::deserialize_identifier(deserializer, ElementFieldVisitor) - } - } - - #[doc(hidden)] - struct Visitor<'s, 'de> { - marker: PhantomData>, - lifetime: PhantomData<&'de ()> - } - impl<'s, 'de> serde::de::Visitor<'de> for Visitor<'s, 'de> { - type Value = Element<'s>; - - fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("enum Element") - } - - fn visit_enum(self, data: A) -> Result - where - A: serde::de::EnumAccess<'de> - { - match serde::de::EnumAccess::variant(data)? { - (ElementField::Text, variant) => serde::de::VariantAccess::newtype_variant::(variant).map(Element::Text), - (ElementField::Audio, variant) => serde::de::VariantAccess::newtype_variant::