Skip to content

Commit

Permalink
feat: Group
Browse files Browse the repository at this point in the history
The main use case here is `VisitMut`; we might want to replace one element with multiple.
  • Loading branch information
decahedron1 committed Dec 16, 2024
1 parent 292a7a9 commit b69aead
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/element.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloc::{borrow::Cow, string::ToString, vec::Vec};
use core::fmt::{Debug, Write};

use crate::{Audio, Break, Emphasis, Mark, Meta, SayAs, Serialize, SerializeOptions, Text, Voice, XmlWriter, util};
use crate::{Audio, Break, Emphasis, Mark, Meta, SayAs, Serialize, SerializeOptions, Text, Voice, XmlWriter, group::Group, util};

macro_rules! el {
(
Expand Down Expand Up @@ -52,6 +52,7 @@ el! {
Emphasis(Emphasis<'s>),
Mark(Mark<'s>),
SayAs(SayAs<'s>),
Group(Group<'s>),
FlavorMSTTS(crate::mstts::Element<'s>),
Custom(CustomElement<'s>)
// Lang(LangElement),
Expand Down
74 changes: 74 additions & 0 deletions src/group.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use core::{
fmt::Write,
ops::{Add, AddAssign}
};

use crate::{Element, Serialize, SerializeOptions, XmlWriter};

#[derive(Clone, Default, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Group<'s> {
pub(crate) children: Vec<Element<'s>>
}

impl<'s> Group<'s> {
pub fn new<S: Into<Element<'s>>, I: IntoIterator<Item = S>>(elements: I) -> Self {
Self {
children: elements.into_iter().map(|f| f.into()).collect()
}
}

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

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) -> Group<'static> {
self.clone().into_owned()
}

pub fn into_owned(self) -> Group<'static> {
Group {
children: self.children.into_iter().map(Element::into_owned).collect()
}
}
}

impl<'s> Serialize for Group<'s> {
fn serialize_xml<W: Write>(&self, writer: &mut XmlWriter<W>, options: &SerializeOptions) -> crate::Result<()> {
for child in &self.children {
child.serialize_xml(writer, options)?;
}
Ok(())
}
}

impl<'s, 's2: 's, T: Into<Element<'s2>>> Add<T> for Group<'s> {
type Output = Group<'s>;

fn add(mut self, rhs: T) -> Self::Output {
self.push(rhs.into());
self
}
}

impl<'s, 's2: 's, T: Into<Element<'s2>>> AddAssign<T> for Group<'s> {
fn add_assign(&mut self, rhs: T) {
self.push(rhs.into());
}
}

pub fn group<'s, S: Into<Element<'s>>, I: IntoIterator<Item = S>>(elements: I) -> Group<'s> {
Group::new(elements)
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ mod r#break;
mod element;
mod emphasis;
mod error;
mod group;
mod mark;
pub mod mstts;
mod say_as;
Expand All @@ -59,6 +60,7 @@ pub use self::{
element::{CustomElement, Element, IntoElement},
emphasis::{Emphasis, EmphasisLevel, emphasis},
error::{Error, Result},
group::{Group, group},
mark::{Mark, mark},
say_as::{DateFormat, SayAs, SpeechFormat, say_as},
speak::{Speak, speak},
Expand Down
4 changes: 2 additions & 2 deletions src/say_as.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloc::borrow::Cow;
use alloc::{borrow::Cow, boxed::Box};
use core::fmt::Write;

use crate::{Flavor, Serialize, SerializeOptions, XmlWriter};
Expand Down Expand Up @@ -124,7 +124,7 @@ impl<'s> SayAs<'s> {

pub fn into_owned(self) -> SayAs<'static> {
SayAs {
format: self.format.to_owned(),
format: self.format.clone(),
text: match self.text {
Cow::Borrowed(b) => Cow::Owned(b.to_string()),
Cow::Owned(b) => Cow::Owned(b)
Expand Down
7 changes: 6 additions & 1 deletion src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,12 @@ pub fn visit_element<'s, V: Visit<'s> + ?Sized>(v: &mut V, node: &'s Element) {
Element::Mark(node) => visit_mark(v, node),
Element::SayAs(node) => visit_say_as(v, node),
Element::FlavorMSTTS(node) => visit_mstts_element(v, node),
Element::Custom(node) => visit_custom(v, node)
Element::Custom(node) => visit_custom(v, node),
Element::Group(node) => {
for child in node.children() {
visit_element(v, child);
}
}
}
}

Expand Down
7 changes: 6 additions & 1 deletion src/visit_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,12 @@ pub fn visit_element_mut<'s, V: VisitMut<'s> + ?Sized>(v: &mut V, node: &'s mut
Element::Mark(node) => visit_mark_mut(v, node),
Element::SayAs(node) => visit_say_as_mut(v, node),
Element::FlavorMSTTS(node) => visit_mstts_element_mut(v, node),
Element::Custom(node) => visit_custom_mut(v, node)
Element::Custom(node) => visit_custom_mut(v, node),
Element::Group(node) => {
for child in node.children_mut() {
visit_element_mut(v, child);
}
}
}
}

Expand Down

0 comments on commit b69aead

Please sign in to comment.