use derive_more::From;
use std::borrow::Cow;
use strong_xml::{XmlRead, XmlWrite};
use crate::{
__setter, __xml_test_suites,
document::{r#break::Break, text::Text},
formatting::CharacterProperty,
};
#[derive(Debug, Default, XmlRead, XmlWrite)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:r")]
pub struct Run<'a> {
#[xml(default, child = "w:rPr")]
pub property: CharacterProperty<'a>,
#[xml(child = "w:t", child = "w:br")]
pub content: Vec<RunContent<'a>>,
}
impl<'a> Run<'a> {
__setter!(property: CharacterProperty<'a>);
#[inline(always)]
pub fn push<T: Into<RunContent<'a>>>(mut self, content: T) -> Self {
self.content.push(content.into());
self
}
#[inline(always)]
pub fn push_text<T: Into<Text<'a>>>(mut self, content: T) -> Self {
self.content.push(RunContent::Text(content.into()));
self
}
#[inline(always)]
pub fn push_break<T: Into<Break>>(mut self, br: T) -> Self {
self.content.push(RunContent::Break(br.into()));
self
}
pub fn iter_text(&self) -> impl Iterator<Item = &Cow<'a, str>> {
self.content.iter().filter_map(|content| match content {
RunContent::Text(Text { text, .. }) => Some(text),
RunContent::Break(_) => None,
})
}
pub fn iter_text_mut(&mut self) -> impl Iterator<Item = &mut Cow<'a, str>> {
self.content.iter_mut().filter_map(|content| match content {
RunContent::Text(Text { text, .. }) => Some(text),
RunContent::Break(_) => None,
})
}
}
#[derive(Debug, From, XmlRead, XmlWrite)]
#[cfg_attr(test, derive(PartialEq))]
pub enum RunContent<'a> {
#[xml(tag = "w:t")]
Text(Text<'a>),
#[xml(tag = "w:br")]
Break(Break),
}
__xml_test_suites!(
Run,
Run::default(),
r#"<w:r><w:rPr/></w:r>"#,
Run::default().push_break(None),
r#"<w:r><w:rPr/><w:br/></w:r>"#,
Run::default().push_text("text"),
r#"<w:r><w:rPr/><w:t>text</w:t></w:r>"#,
);