#![allow(unused_must_use)]
use derive_more::From;
use hard_xml::{XmlRead, XmlWrite};
use std::borrow::Cow;
use crate::{
__setter, __xml_test_suites,
document::{
drawing::Drawing, field_char::FieldChar, instrtext::InstrText, r#break::Break,
r#break::LastRenderedPageBreak, tab::Tab, text::Text,
},
formatting::CharacterProperty,
DocxResult, __define_enum, __define_struct,
};
use super::{
date::{DayLong, DayShort, MonthLong, MonthShort, YearLong, YearShort},
instrtext::DelInstrText,
sym::Sym,
AnnotationRef, CarriageReturn, CommentReference, DelText, EndnoteRef, EndnoteReference,
FootnoteRef, FootnoteReference,
};
#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:r")]
pub struct Run<'a> {
#[xml(attr = "w:rsidR")]
pub rsid_r: Option<Cow<'a, str>>,
#[xml(attr = "w:rsidRDefault")]
pub rsid_r_default: Option<Cow<'a, str>>,
#[xml(child = "w:rPr")]
pub property: Option<CharacterProperty<'a>>,
#[xml(
child = "w:br", child = "w:t", child = "w:delText", child = "w:instrText", child = "w:delInstrText", child = "w:noBreakHyphen", child = "w:softHyphen", child = "w:dayShort", child = "w:monthShort", child = "w:yearShort", child = "w:dayLong", child = "w:monthLong", child = "w:yearLong", child = "w:annotationRef", child = "w:footnoteRef", child = "w:endnoteRef", child = "w:separator", child = "w:continuationSeparator", child = "w:sym", child = "w:pgNum", child = "w:cr", child = "w:tab", child = "w:fldChar", child = "w:footnoteReference", child = "w:endnoteReference", child = "w:commentReference", child = "w:drawing", child = "w:ptab", child = "w:lastRenderedPageBreak", )]
pub content: Vec<RunContent<'a>>,
}
impl<'a> Run<'a> {
__setter!(property: Option<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::InstrText(InstrText { text, .. }) => Some(text),
RunContent::Break(_) => None,
RunContent::LastRenderedPageBreak(_) => None,
RunContent::FieldChar(_) => None,
RunContent::Separator(_) => None,
RunContent::ContinuationSeparator(_) => None,
RunContent::Tab(_) => None,
RunContent::CarriageReturn(_) => None,
RunContent::Drawing(_) => None,
_ => 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::InstrText(InstrText { text, .. }) => Some(text),
RunContent::Break(_) => None,
RunContent::LastRenderedPageBreak(_) => None,
RunContent::FieldChar(_) => None,
RunContent::Separator(_) => None,
RunContent::ContinuationSeparator(_) => None,
RunContent::Tab(_) => None,
RunContent::CarriageReturn(_) => None,
RunContent::Drawing(_) => None,
_ => None,
})
}
pub fn replace_text_simple<S>(&mut self, old: S, new: S)
where
S: AsRef<str>,
{
let dic = (old, new);
let dic = vec![dic];
self.replace_text(&dic);
}
pub fn replace_text<'b, T, S>(&mut self, dic: T) -> DocxResult<()>
where
S: AsRef<str> + 'b,
T: IntoIterator<Item = &'b (S, S)> + std::marker::Copy,
{
for c in self.content.iter_mut() {
match c {
RunContent::Text(t) => {
let mut tc = t.text.to_string();
for p in dic {
tc = tc.replace(p.0.as_ref(), p.1.as_ref());
}
t.text = tc.into();
}
_ => {}
}
}
Ok(())
}
}
#[derive(Debug, From, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
pub enum RunContent<'a> {
#[xml(tag = "w:br")]
Break(Break),
#[xml(tag = "w:t")]
Text(Text<'a>),
#[xml(tag = "w:delText")]
DelText(DelText<'a>),
#[xml(tag = "w:instrText")]
InstrText(InstrText<'a>),
#[xml(tag = "w:delInstrText")]
DelInstrText(DelInstrText<'a>),
#[xml(tag = "w:noBreakHyphen")]
NoBreakHyphen(NoBreakHyphen),
#[xml(tag = "w:softHyphen")]
SoftHyphen(SoftHyphen),
#[xml(tag = "w:dayShort")]
DayShort(DayShort),
#[xml(tag = "w:monthShort")]
MonthShort(MonthShort),
#[xml(tag = "w:yearShort")]
YearShort(YearShort),
#[xml(tag = "w:dayLong")]
DayLong(DayLong),
#[xml(tag = "w:monthLong")]
MonthLong(MonthLong),
#[xml(tag = "w:yearLong")]
YearLong(YearLong),
#[xml(tag = "w:annotationRef")]
AnnotationRef(AnnotationRef),
#[xml(tag = "w:footnoteRef")]
FootnoteRef(FootnoteRef),
#[xml(tag = "w:endnoteRef")]
EndnoteRef(EndnoteRef),
#[xml(tag = "w:separator")]
Separator(Separator),
#[xml(tag = "w:continuationSeparator")]
ContinuationSeparator(ContinuationSeparator),
#[xml(tag = "w:sym")]
Sym(Sym<'a>),
#[xml(tag = "w:pgNum")]
PgNum(PgNum),
#[xml(tag = "w:cr")]
CarriageReturn(CarriageReturn),
#[xml(tag = "w:tab")]
Tab(Tab),
#[xml(tag = "w:fldChar")]
FieldChar(FieldChar),
#[xml(tag = "w:footnoteReference")]
FootnoteReference(FootnoteReference<'a>),
#[xml(tag = "w:endnoteReference")]
EndnoteReference(EndnoteReference<'a>),
#[xml(tag = "w:commentReference")]
CommentReference(CommentReference<'a>),
#[xml(tag = "w:drawing")]
Drawing(Drawing<'a>),
#[xml(tag = "w:ptab")]
PTab(PTab),
#[xml(tag = "w:lastRenderedPageBreak")]
LastRenderedPageBreak(LastRenderedPageBreak),
}
__define_struct! {
("w:ptab", PTab) {
"w:alignment", alignment, PTabAlignment "w:relativeTo", relative_to, PTabRelativeTo "w:leader", leader, PTabLeader }
}
__define_enum! {
PTabAlignment {
Left = "left", Center = "center", Right = "right", }
}
__define_enum! {
PTabRelativeTo {
Margin = "margin", Indent = "indent", }
}
__define_enum! {
PTabLeader {
None = "none", Dot = "dot", Hyphen = "hyphen", Underscore = "underscore", MiddleDot = "middleDot", }
}
#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:noBreakHyphen")]
pub struct NoBreakHyphen;
#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:softHyphen")]
pub struct SoftHyphen {}
#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:separator")]
pub struct Separator {}
#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:continuationSeparator")]
pub struct ContinuationSeparator {}
#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:pgNum")]
pub struct PgNum {}
__xml_test_suites!(
Run,
Run::default(),
r#"<w:r/>"#,
Run::default().push_break(None),
r#"<w:r><w:br/></w:r>"#,
Run::default().push_text("text"),
r#"<w:r><w:t>text</w:t></w:r>"#,
);