Skip to content

Commit

Permalink
feat: mutable attribute methods for all elements
Browse files Browse the repository at this point in the history
makes `VisitMut` more useful
  • Loading branch information
decahedron1 committed Nov 11, 2024
1 parent 6cfd74a commit 11c5b8f
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 32 deletions.
82 changes: 81 additions & 1 deletion src/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ impl<'s> Audio<'s> {
Audio { src: src.into(), ..Audio::default() }
}

pub fn src(&self) -> &str {
&self.src
}

pub fn set_src(&mut self, src: impl Into<Cow<'s, str>>) {
self.src = src.into();
}

/// Appends alternate (fallback) elements. Alternate elements will be spoken or displayed if the audio document
/// located at the specified URI is unavailable for whatever reason.
///
Expand All @@ -68,6 +76,18 @@ impl<'s> Audio<'s> {
self
}

pub fn desc(&self) -> Option<&str> {
self.desc.as_deref()
}

pub fn set_desc(&mut self, desc: impl Into<Cow<'s, str>>) {
self.desc = Some(desc.into());
}

pub fn take_desc(&mut self) -> Option<Cow<'s, str>> {
self.desc.take()
}

/// Specify an offset from the beginning and to the end of which to clip this audio's duration to.
///
/// ```
Expand All @@ -90,6 +110,18 @@ impl<'s> Audio<'s> {
self
}

pub fn clip_begin(&self) -> Option<&TimeDesignation> {
self.clip.0.as_ref()
}

pub fn set_clip_begin(&mut self, begin: impl Into<TimeDesignation>) {
self.clip.0 = Some(begin.into());
}

pub fn take_clip_begin(&mut self) -> Option<TimeDesignation> {
self.clip.0.take()
}

/// Specify an offset from the beginning of the audio to end playback.
///
/// ```
Expand All @@ -101,6 +133,18 @@ impl<'s> Audio<'s> {
self
}

pub fn clip_end(&self) -> Option<&TimeDesignation> {
self.clip.1.as_ref()
}

pub fn set_clip_end(&mut self, end: impl Into<TimeDesignation>) {
self.clip.1 = Some(end.into());
}

pub fn take_clip_end(&mut self) -> Option<TimeDesignation> {
self.clip.1.take()
}

/// Repeat this audio source for a set amount of times, or for a set duration. See [`AudioRepeat`].
///
/// ```
Expand All @@ -114,6 +158,18 @@ impl<'s> Audio<'s> {
self
}

pub fn repeat(&self) -> Option<&AudioRepeat> {
self.repeat.as_ref()
}

pub fn set_repeat(&mut self, repeat: AudioRepeat) {
self.repeat = Some(repeat);
}

pub fn take_repeat(&mut self) -> Option<AudioRepeat> {
self.repeat.take()
}

/// Specify the relative volume of the referenced audio, in decibels. Setting to a large negative value like
/// `-100dB` will effectively silence the audio clip. A value of `-6.0dB` will play the audio at approximately half
/// the volume, and likewise `+6.0dB` will play the audio at twice the volume.
Expand All @@ -126,6 +182,18 @@ impl<'s> Audio<'s> {
self
}

pub fn sound_level(&self) -> Option<&Decibels> {
self.sound_level.as_ref()
}

pub fn set_sound_level(&mut self, db: impl Into<Decibels>) {
self.sound_level = Some(db.into());
}

pub fn take_sound_level(&mut self) -> Option<Decibels> {
self.sound_level.take()
}

/// Specify the speed at which to play the audio clip (where `1.0` is normal speed).
///
/// ```
Expand All @@ -137,13 +205,25 @@ impl<'s> Audio<'s> {
self
}

pub fn speed(&self) -> Option<f32> {
self.speed
}

pub fn set_speed(&mut self, speed: f32) {
self.speed = Some(speed.into());
}

pub fn take_speed(&mut self) -> Option<f32> {
self.speed.take()
}

/// Returns a reference to the elements contained in this `audio` element's alternate/fallback section.
pub fn alternate(&self) -> &[Element<'s>] {
&self.alternate
}

/// Returns a reference to the elements contained in this `audio` element's alternate/fallback section.
pub fn alternate_mut(&mut self) -> &mut [Element<'s>] {
pub fn alternate_mut(&mut self) -> &mut Vec<Element<'s>> {
&mut self.alternate
}

Expand Down
22 changes: 13 additions & 9 deletions src/emphasis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,30 @@ impl<'s> Emphasis<'s> {
}
}

pub fn push(&mut self, element: impl Into<Element<'s>>) {
self.children.push(element.into());
}

pub fn extend<S: Into<Element<'s>>, I: IntoIterator<Item = S>>(&mut self, elements: I) {
self.children.extend(elements.into_iter().map(|f| f.into()));
}

pub fn level(&self) -> &EmphasisLevel {
&self.level
}

pub fn set_level(&mut self, level: EmphasisLevel) {
self.level = level;
}

pub fn children(&self) -> &[Element<'s>] {
&self.children
}

pub fn children_mut(&mut self) -> &mut [Element<'s>] {
pub fn children_mut(&mut self) -> &mut Vec<Element<'s>> {
&mut self.children
}

pub fn push(&mut self, element: impl Into<Element<'s>>) {
self.children.push(element.into());
}

pub fn extend<S: Into<Element<'s>>, I: IntoIterator<Item = S>>(&mut self, elements: I) {
self.children.extend(elements.into_iter().map(|f| f.into()));
}

pub fn to_owned(&self) -> Emphasis<'static> {
self.clone().into_owned()
}
Expand Down
4 changes: 4 additions & 0 deletions src/mark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ impl<'s> Mark<'s> {
&self.name
}

pub fn set_name(&mut self, name: impl Into<Cow<'s, str>>) {
self.name = name.into();
}

pub fn to_owned(&self) -> Mark<'static> {
self.clone().into_owned()
}
Expand Down
43 changes: 37 additions & 6 deletions src/mstts/express.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloc::{string::String, vec::Vec};
use alloc::{borrow::Cow, vec::Vec};
use core::fmt::Write;

use crate::{Element, Serialize, SerializeOptions, XmlWriter, util};
Expand All @@ -7,7 +7,30 @@ use crate::{Element, Serialize, SerializeOptions, XmlWriter, util};
/// `1.0`).
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Expression(String, f32);
pub struct Expression(Cow<'static, str>, f32);

impl Expression {
pub fn new(name: impl Into<Cow<'static, str>>) -> Self {
Self(name.into(), 1.0)
}

pub fn name(&self) -> &str {
&self.0
}

pub fn degree(&self) -> f32 {
self.1
}

pub fn with_degree(mut self, degree: f32) -> Self {
self.1 = degree.clamp(0.01, 2.0);
self
}

pub fn set_degree(&mut self, degree: f32) {
self.1 = degree.clamp(0.01, 2.0);
}
}

macro_rules! define_expressions {
($($(#[$outer:meta])* $x:ident => $e:expr),*) => {
Expand All @@ -21,7 +44,7 @@ macro_rules! define_expressions {

impl From<$x> for Expression {
fn from(_: $x) -> Expression {
Expression(String::from($e), 1.0)
Expression(Cow::Borrowed($e), 1.0)
}
}

Expand All @@ -32,7 +55,7 @@ macro_rules! define_expressions {
/// results in a slight tendency for the target style. A value of `2` results in a doubling of the
/// default style intensity.
pub fn with_degree(&self, degree: f32) -> Expression {
Expression(String::from($e), degree.clamp(0.01, 2.0))
Expression(Cow::Borrowed($e), degree.clamp(0.01, 2.0))
}
}
)*
Expand Down Expand Up @@ -166,6 +189,14 @@ impl<'s> Express<'s> {
}
}

pub fn expression(&self) -> &Expression {
&self.expression
}

pub fn set_expression(&mut self, expression: impl Into<Expression>) {
self.expression = expression.into();
}

/// Extend this `express-as` section with an additional element.
pub fn push(&mut self, element: impl Into<Element<'s>>) {
self.children.push(element.into());
Expand All @@ -182,7 +213,7 @@ impl<'s> Express<'s> {
}

/// Returns a mutable reference to the elements contained within this `voice` section.
pub fn children_mut(&mut self) -> &mut [Element<'s>] {
pub fn children_mut(&mut self) -> &mut Vec<Element<'s>> {
&mut self.children
}

Expand All @@ -201,7 +232,7 @@ impl<'s> From<Express<'s>> for crate::Element<'s> {
impl<'s> Serialize for Express<'s> {
fn serialize_xml<W: Write>(&self, writer: &mut XmlWriter<W>, options: &SerializeOptions) -> crate::Result<()> {
writer.element("mstts:express-as", |writer| {
writer.attr("style", &self.expression.0)?;
writer.attr("style", &*self.expression.0)?;
writer.attr("styledegree", self.expression.1)?;
util::serialize_elements(writer, &self.children, options)
})
Expand Down
26 changes: 25 additions & 1 deletion src/speak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,35 @@ impl<'s> Speak<'s> {
self
}

pub fn start_mark(&self) -> Option<&str> {
self.marks.0.as_deref()
}

pub fn set_start_mark(&mut self, mark: impl Into<Cow<'s, str>>) {
self.marks.0 = Some(mark.into());
}

pub fn take_start_mark(&mut self) -> Option<Cow<'s, str>> {
self.marks.0.take()
}

pub fn with_end_mark(mut self, mark: impl Into<Cow<'s, str>>) -> Self {
self.marks.1 = Some(mark.into());
self
}

pub fn end_mark(&self) -> Option<&str> {
self.marks.1.as_deref()
}

pub fn set_end_mark(&mut self, mark: impl Into<Cow<'s, str>>) {
self.marks.1 = Some(mark.into());
}

pub fn take_end_mark(&mut self) -> Option<Cow<'s, str>> {
self.marks.1.take()
}

/// Extend this SSML document with an additional element.
///
/// ```
Expand Down Expand Up @@ -89,7 +113,7 @@ impl<'s> Speak<'s> {
}

/// Returns a mutable reference to the document's direct children.
pub fn children_mut(&mut self) -> &mut [Element<'s>] {
pub fn children_mut(&mut self) -> &mut Vec<Element<'s>> {
&mut self.children
}

Expand Down
8 changes: 8 additions & 0 deletions src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ impl<'s> Text<'s> {
self.clone().into_owned()
}

pub fn as_str(&self) -> &str {
&*self.0
}

pub fn set(&mut self, text: impl Into<Cow<'s, str>>) {
self.0 = text.into();
}

pub fn into_owned(self) -> Text<'static> {
Text(match self.0 {
Cow::Borrowed(b) => Cow::Owned(b.to_string()),
Expand Down
24 changes: 17 additions & 7 deletions src/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ impl TimeDesignation {
}

/// Convert this time designation to milliseconds.
pub fn as_millis(&self) -> &f32 {
&self.millis
pub fn to_millis(&self) -> f32 {
self.millis
}
}

Expand Down Expand Up @@ -98,7 +98,7 @@ impl From<&str> for TimeDesignation {

impl Display for TimeDesignation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("{:+}ms", self.as_millis()))
f.write_fmt(format_args!("{:+}ms", self.to_millis()))
}
}
impl TrustedNoEscape for TimeDesignation {}
Expand Down Expand Up @@ -134,9 +134,9 @@ impl std::error::Error for DecibelsError {}
/// ```
/// # use ssml::Decibels;
/// # fn main() -> ssml::Result<()> {
/// assert_eq!("+0.0dB".parse::<Decibels>()?, Decibels(0.));
/// assert_eq!("-6dB".parse::<Decibels>()?, Decibels(-6.));
/// assert_eq!("2dB".parse::<Decibels>()?, Decibels(2.));
/// assert_eq!("+0.0dB".parse::<Decibels>()?, Decibels::new(0.));
/// assert_eq!("-6dB".parse::<Decibels>()?, Decibels::new(-6.));
/// assert_eq!("2dB".parse::<Decibels>()?, Decibels::new(2.));
///
/// // Fails
/// assert!("-3DB".parse::<Decibels>().is_err());
Expand All @@ -147,7 +147,17 @@ impl std::error::Error for DecibelsError {}
/// ```
#[derive(Default, Clone, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Decibels(pub f32);
pub struct Decibels(f32);

impl Decibels {
pub fn new(value: f32) -> Self {
Self(value)
}

pub fn value(&self) -> f32 {
self.0
}
}

impl FromStr for Decibels {
type Err = DecibelsError;
Expand Down
Loading

0 comments on commit 11c5b8f

Please sign in to comment.