1#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
28#![allow(clippy::tabs_in_doc_comments)]
29
30extern crate alloc;
31extern crate core;
32
33use alloc::{
34 borrow::Cow,
35 string::{String, ToString}
36};
37use core::fmt::{Debug, Write};
38
39mod audio;
40mod r#break;
41mod element;
42mod emphasis;
43mod error;
44mod group;
45mod lang;
46mod mark;
47pub mod mstts;
48mod prosody;
49mod say_as;
50mod speak;
51mod text;
52mod unit;
53pub mod util;
54pub mod visit;
55pub mod visit_mut;
56mod voice;
57mod xml;
58
59pub use self::{
60 audio::{Audio, AudioRepeat, audio},
61 r#break::{Break, BreakStrength, breaks},
62 element::{CustomElement, Element, IntoElement},
63 emphasis::{Emphasis, EmphasisLevel, emphasis},
64 error::{Error, Result},
65 group::{Group, group},
66 lang::{Lang, lang},
67 mark::{Mark, mark},
68 prosody::{Prosody, ProsodyContour, ProsodyControl, ProsodyPitch, ProsodyRate, ProsodyVolume, prosody},
69 say_as::{DateFormat, SayAs, SpeechFormat, say_as},
70 speak::{Speak, speak},
71 text::{Text, text},
72 unit::{Decibels, DecibelsError, TimeDesignation, TimeDesignationError},
73 voice::{Voice, VoiceConfig, VoiceGender, voice},
74 xml::{EscapedDisplay, XmlWriter}
75};
76
77#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
80#[non_exhaustive]
81#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
82pub enum Flavor {
83 #[default]
87 Generic,
88 MicrosoftAzureCognitiveSpeechServices,
92 GoogleCloudTextToSpeech,
94 AmazonPolly,
100 PykeSongbird
102}
103
104#[derive(Debug, Clone)]
106#[non_exhaustive]
107pub struct SerializeOptions {
108 pub flavor: Flavor,
111 pub pretty: bool
116}
117
118impl Default for SerializeOptions {
119 fn default() -> Self {
120 SerializeOptions {
121 flavor: Flavor::Generic,
122 pretty: false
123 }
124 }
125}
126
127impl SerializeOptions {
128 pub fn min(mut self) -> Self {
129 self.pretty = false;
130 self
131 }
132
133 pub fn pretty(mut self) -> Self {
134 self.pretty = true;
135 self
136 }
137
138 pub fn flavor(mut self, flavor: Flavor) -> Self {
139 self.flavor = flavor;
140 self
141 }
142}
143
144pub trait Serialize {
146 fn serialize<W: Write>(&self, writer: &mut W, options: &SerializeOptions) -> crate::Result<()> {
148 let mut writer = XmlWriter::new(writer, options.pretty);
149 self.serialize_xml(&mut writer, options)?;
150 Ok(())
151 }
152
153 fn serialize_xml<W: Write>(&self, writer: &mut XmlWriter<W>, options: &SerializeOptions) -> crate::Result<()>;
155
156 fn serialize_to_string(&self, options: &SerializeOptions) -> crate::Result<String> {
158 let mut out = String::new();
159 self.serialize(&mut out, options)?;
160 Ok(out)
161 }
162}
163
164#[derive(Debug, Clone)]
169#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
170pub struct Meta<'s> {
171 raw: Cow<'s, str>,
172 name: Option<Cow<'s, str>>
173}
174
175impl<'s> Meta<'s> {
176 pub fn new(xml: impl Into<Cow<'s, str>>) -> Self {
177 Meta { raw: xml.into(), name: None }
178 }
179
180 pub fn with_name(mut self, name: impl Into<Cow<'s, str>>) -> Self {
181 self.name = Some(name.into());
182 self
183 }
184
185 pub fn to_owned(&self) -> Meta<'static> {
186 self.clone().into_owned()
187 }
188
189 pub fn into_owned(self) -> Meta<'static> {
190 Meta {
191 raw: match self.raw {
192 Cow::Borrowed(b) => Cow::Owned(b.to_string()),
193 Cow::Owned(b) => Cow::Owned(b)
194 },
195 name: match self.name {
196 Some(Cow::Borrowed(b)) => Some(Cow::Owned(b.to_string())),
197 Some(Cow::Owned(b)) => Some(Cow::Owned(b)),
198 None => None
199 }
200 }
201 }
202}
203
204impl<'s> Serialize for Meta<'s> {
205 fn serialize_xml<W: Write>(&self, writer: &mut XmlWriter<W>, _: &SerializeOptions) -> crate::Result<()> {
206 writer.raw(&self.raw)
207 }
208}