docx_rs/documents/elements/
footnote.rs1use serde::Serialize;
2use std::io::Write;
3
4use crate::documents::*;
5use crate::xml_builder::*;
6use footnote_id::generate_footnote_id;
7
8#[derive(Serialize, Debug, Clone, PartialEq)]
9#[serde(rename_all = "camelCase")]
10pub struct Footnote {
11 pub id: usize,
12 pub content: Vec<Paragraph>,
13}
14
15impl Default for Footnote {
16 fn default() -> Self {
17 Footnote {
18 id: 1,
19 content: vec![],
20 }
21 }
22}
23
24impl Footnote {
25 pub fn new() -> Self {
26 Self {
27 id: generate_footnote_id(),
28 ..Default::default()
29 }
30 }
31
32 pub fn id(&self) -> usize {
33 self.id
34 }
35
36 pub fn add_content(&mut self, p: Paragraph) -> Self {
37 self.content.push(p);
38 self.clone()
39 }
40}
41impl From<&FootnoteReference> for Footnote {
42 fn from(reference: &FootnoteReference) -> Self {
43 Footnote {
44 id: reference.id,
45 content: reference.content.clone(),
46 }
47 }
48}
49
50impl BuildXML for Footnote {
51 fn build_to<W: Write>(
52 &self,
53 stream: xml::writer::EventWriter<W>,
54 ) -> xml::writer::Result<xml::writer::EventWriter<W>> {
55 let mut footnote = self.clone();
57 if self.content == vec![] {
58 eprintln!("{:?}", footnote);
59 footnote.add_content(Paragraph::new());
60 }
61
62 XMLBuilder::from(stream)
63 .open_footnote(&format!("{}", self.id))?
64 .add_children(&footnote.content)?
65 .close()?
66 .into_inner()
67 }
68}
69
70#[cfg(test)]
71mod tests {
72
73 use super::*;
74 #[cfg(test)]
75 use pretty_assertions::assert_eq;
76 use std::str;
77
78 #[test]
79 fn test_footnote_build_default() {
80 let b = Footnote::new().build();
81 assert_eq!(
82 str::from_utf8(&b).unwrap(),
83 r#"<w:footnote w:id="1"><w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr></w:p></w:footnote>"#
84 );
85 }
86
87 #[test]
88 fn test_footnote_build_with_paragraph() {
89 let b = Footnote::new()
90 .add_content(Paragraph::new().add_run(Run::new().add_text("hello")))
91 .build();
92 assert_eq!(
93 str::from_utf8(&b).unwrap(),
94 r#"<w:footnote w:id="1"><w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">hello</w:t></w:r></w:p></w:footnote>"#
95 );
96 }
97}