docx_rust/styles/
style.rs

1#![allow(unused_must_use)]
2use hard_xml::{XmlRead, XmlWrite};
3use std::borrow::Cow;
4
5use crate::{
6    __setter, __string_enum, __xml_test_suites,
7    formatting::{CharacterProperty, ParagraphProperty, TableProperty},
8};
9
10use crate::styles::priority::Priority;
11
12/// Style
13///
14/// A style that applied to a region of the document.
15///
16/// ```rust
17/// use docx_rust::formatting::*;
18/// use docx_rust::styles::*;
19///
20/// let style = Style::new(StyleType::Paragraph, "style_id")
21///     .name("Style Name")
22///     .paragraph(ParagraphProperty::default())
23///     .character(CharacterProperty::default());
24/// ```
25#[derive(Debug, XmlRead, XmlWrite, Clone)]
26#[cfg_attr(test, derive(PartialEq))]
27#[xml(tag = "w:style")]
28pub struct Style<'a> {
29    /// Specifies the type of style.
30    #[xml(attr = "w:type")]
31    pub ty: Option<StyleType>,
32    /// Specifies the unique identifier
33    ///
34    /// This identifier is used throughout the document to apply style in content.
35    #[xml(attr = "w:styleId")]
36    pub style_id: Cow<'a, str>,
37    #[xml(attr = "w:default")]
38    pub default: Option<bool>,
39    #[xml(attr = "w:customStyle")]
40    pub custom_style: Option<bool>,
41
42    /// Specifies the primary name
43    #[xml(child = "w:name")]
44    pub name: Option<StyleName<'a>>,
45    #[xml(child = "w:aliases")]
46    pub aliases: Option<Aliases<'a>>,
47    #[xml(child = "w:basedOn")]
48    pub base: Option<BasedOn<'a>>,
49    /// Style For Next Paragraph
50    #[xml(child = "w:next")]
51    pub next: Option<Next<'a>>,
52    #[xml(child = "w:link")]
53    pub link: Option<Link<'a>>,
54    #[xml(child = "w:autoRedefine")]
55    pub auto_redefine: Option<AutoRedefine>,
56    #[xml(child = "w:hidden")]
57    pub hidden: Option<Hidden>,
58    /// Specifies the priority.
59    #[xml(child = "w:uiPriority")]
60    pub priority: Option<Priority>,
61    #[xml(child = "w:semiHidden")]
62    pub semi_hidden: Option<super::semi_hidden::SemiHidden>,
63    #[xml(child = "w:unhideWhenUsed")]
64    pub unhide_when_used: Option<super::unhidden_when_used::UnhideWhenUsed>,
65    #[xml(child = "w:qFormat")]
66    pub q_format: Option<QFormat>,
67    /// Style Cannot Be Applied
68    #[xml(child = "w:locked")]
69    pub locked: Option<Locked>,
70    /// E-Mail Message Text Style
71    #[xml(child = "w:personal")]
72    pub personal: Option<Personal>,
73    /// E-Mail Message Composition Style
74    #[xml(child = "w:personalCompose")]
75    pub personal_compose: Option<PersonalCompose>,
76    /// E-Mail Message Reply Style
77    #[xml(child = "w:personalReply")]
78    pub personal_reply: Option<PersonalReply>,
79    #[xml(child = "w:rsid")]
80    pub rsid: Option<Rsid<'a>>,
81    /// Specifies a set of paragraph properties
82    #[xml(default, child = "w:pPr")]
83    pub paragraph: Option<ParagraphProperty<'a>>,
84    /// Specifies a set of character properties
85    #[xml(default, child = "w:rPr")]
86    pub character: Option<CharacterProperty<'a>>,
87    #[xml(default, child = "w:tblPr")]
88    pub table: Option<TableProperty<'a>>,
89    #[xml(child = "w:trPr")]
90    pub table_row: Option<crate::formatting::TableRowProperty>,
91    #[xml(child = "w:tcPr")]
92    pub table_cell: Option<crate::formatting::TableCellProperty>,
93    #[xml(child = "w:tblStylePr")]
94    pub conditional_table_property: Vec<crate::formatting::ConditionalTableProperty<'a>>,
95}
96
97impl<'a> Style<'a> {
98    pub fn new<T: Into<Cow<'a, str>>>(ty: StyleType, style_id: T) -> Self {
99        Style {
100            ty: Some(ty),
101            style_id: style_id.into(),
102            default: None,
103            custom_style: None,
104            name: None,
105            base: None,
106            q_format: None,
107            priority: None,
108            semi_hidden: None,
109            unhide_when_used: None,
110            paragraph: None,
111            character: None,
112            table: None,
113            aliases: None,
114            next: None,
115            link: None,
116            auto_redefine: None,
117            hidden: None,
118            locked: None,
119            personal: None,
120            personal_compose: None,
121            personal_reply: None,
122            rsid: None,
123            table_row: None,
124            table_cell: None,
125            conditional_table_property: Vec::new(),
126        }
127    }
128
129    __setter!(ty: Option<StyleType>);
130    __setter!(name: Option<StyleName<'a>>);
131    __setter!(paragraph: Option<ParagraphProperty<'a>>);
132    __setter!(character: Option<CharacterProperty<'a>>);
133}
134
135#[derive(Debug, XmlRead, XmlWrite, Clone)]
136#[cfg_attr(test, derive(PartialEq))]
137#[xml(tag = "w:name")]
138pub struct StyleName<'a> {
139    #[xml(attr = "w:val")]
140    pub value: Cow<'a, str>,
141}
142
143impl<'a, S: Into<Cow<'a, str>>> From<S> for StyleName<'a> {
144    fn from(val: S) -> Self {
145        StyleName { value: val.into() }
146    }
147}
148
149#[derive(Debug, XmlRead, XmlWrite, Clone)]
150#[cfg_attr(test, derive(PartialEq))]
151#[xml(tag = "w:aliases")]
152pub struct Aliases<'a> {
153    #[xml(attr = "w:val")]
154    pub value: Cow<'a, str>,
155}
156
157#[derive(Debug, XmlRead, XmlWrite, Clone)]
158#[cfg_attr(test, derive(PartialEq))]
159#[xml(tag = "w:next")]
160pub struct Next<'a> {
161    #[xml(attr = "w:val")]
162    pub value: Cow<'a, str>,
163}
164
165#[derive(Debug, XmlRead, XmlWrite, Clone)]
166#[cfg_attr(test, derive(PartialEq))]
167#[xml(tag = "w:link")]
168pub struct Link<'a> {
169    #[xml(attr = "w:val")]
170    pub value: Cow<'a, str>,
171}
172
173#[derive(Debug, XmlRead, XmlWrite, Clone)]
174#[cfg_attr(test, derive(PartialEq))]
175#[xml(tag = "w:autoRedefine")]
176pub struct AutoRedefine {
177    #[xml(attr = "w:val")]
178    pub value: Option<bool>,
179}
180
181#[derive(Debug, XmlRead, XmlWrite, Clone)]
182#[cfg_attr(test, derive(PartialEq))]
183#[xml(tag = "w:hidden")]
184pub struct Hidden {
185    #[xml(attr = "w:val")]
186    pub value: Option<bool>,
187}
188
189#[derive(Debug, XmlRead, XmlWrite, Clone)]
190#[cfg_attr(test, derive(PartialEq))]
191#[xml(tag = "w:locked")]
192pub struct Locked {
193    #[xml(attr = "w:val")]
194    pub value: Option<bool>,
195}
196
197#[derive(Debug, XmlRead, XmlWrite, Clone)]
198#[cfg_attr(test, derive(PartialEq))]
199#[xml(tag = "w:personal")]
200pub struct Personal {
201    #[xml(attr = "w:val")]
202    pub value: Option<bool>,
203}
204
205#[derive(Debug, XmlRead, XmlWrite, Clone)]
206#[cfg_attr(test, derive(PartialEq))]
207#[xml(tag = "w:personalCompose")]
208pub struct PersonalCompose {
209    #[xml(attr = "w:val")]
210    pub value: Option<bool>,
211}
212
213#[derive(Debug, XmlRead, XmlWrite, Clone)]
214#[cfg_attr(test, derive(PartialEq))]
215#[xml(tag = "w:personalReply")]
216pub struct PersonalReply {
217    #[xml(attr = "w:val")]
218    pub value: Option<bool>,
219}
220
221#[derive(Debug, XmlRead, XmlWrite, Clone)]
222#[cfg_attr(test, derive(PartialEq))]
223#[xml(tag = "w:rsid")]
224pub struct Rsid<'a> {
225    #[xml(attr = "w:val")]
226    pub value: Cow<'a, str>,
227}
228
229#[derive(Debug, XmlRead, XmlWrite, Clone)]
230#[cfg_attr(test, derive(PartialEq))]
231#[xml(tag = "w:basedOn")]
232pub struct BasedOn<'a> {
233    #[xml(attr = "w:val")]
234    pub value: Cow<'a, str>,
235}
236
237#[derive(Debug, XmlRead, XmlWrite, Clone)]
238#[cfg_attr(test, derive(PartialEq))]
239#[xml(tag = "w:qFormat")]
240pub struct QFormat {
241    #[xml(attr = "w:val")]
242    pub value: Option<bool>,
243}
244
245#[derive(Debug, Clone)]
246#[cfg_attr(test, derive(PartialEq))]
247pub enum StyleType {
248    Character,
249    Paragraph,
250    Table,
251    Numbering,
252}
253
254__string_enum! {
255    StyleType {
256        Character = "character",
257        Paragraph = "paragraph",
258        Table = "table",
259        Numbering = "numbering",
260    }
261}
262
263__xml_test_suites!(
264    Style,
265    Style::new(StyleType::Numbering, "id"),
266    r#"<w:style w:type="numbering" w:styleId="id"/>"#,
267    Style::new(StyleType::Table, "id").name("name"),
268    r#"<w:style w:type="table" w:styleId="id"><w:name w:val="name"/></w:style>"#,
269    Style::new(StyleType::Paragraph, "id"),
270    r#"<w:style w:type="paragraph" w:styleId="id"/>"#,
271    Style::new(StyleType::Character, "id"),
272    r#"<w:style w:type="character" w:styleId="id"/>"#,
273);