easyofd_core/annotation/
annotations.rs1use std::fmt::Write;
4
5use super::ann_page::AnnPage;
6
7#[derive(Debug, Clone)]
11pub struct Annotations {
12 pub doc_id: Option<String>,
14 pub pages: Vec<AnnPage>,
16}
17
18impl Annotations {
19 #[must_use]
21 pub fn new() -> Self {
22 Self {
23 doc_id: None,
24 pages: Vec::new(),
25 }
26 }
27
28 #[must_use]
30 pub fn doc_id(mut self, id: impl Into<String>) -> Self {
31 self.doc_id = Some(id.into());
32 self
33 }
34
35 #[must_use]
37 pub fn add_page(mut self, page: AnnPage) -> Self {
38 self.pages.push(page);
39 self
40 }
41
42 #[must_use]
44 pub fn to_xml_string(&self) -> String {
45 let mut xml = String::from(r#"<?xml version="1.0" encoding="UTF-8"?>"#);
46 xml.push('\n');
47 xml.push_str(r#"<ofd:Annotations xmlns:ofd="http://www.ofdspec.org/2016""#);
48 if let Some(ref doc_id) = self.doc_id {
49 let _ = write!(xml, r#" DocID="{doc_id}""#);
50 }
51 xml.push('>');
52 for page in &self.pages {
53 xml.push('\n');
54 xml.push_str(&page.to_xml_string());
55 }
56 xml.push_str("\n</ofd:Annotations>");
57 xml
58 }
59}
60
61impl Default for Annotations {
62 fn default() -> Self {
63 Self::new()
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn test_annotations_new() {
73 let a = Annotations::new();
74 assert!(a.doc_id.is_none());
75 assert!(a.pages.is_empty());
76 }
77
78 #[test]
79 fn test_annotations_default() {
80 let a = Annotations::default();
81 assert!(a.pages.is_empty());
82 }
83
84 #[test]
85 fn test_annotations_builder() {
86 let a = Annotations::new()
87 .doc_id("doc-001")
88 .add_page(AnnPage::new(0))
89 .add_page(AnnPage::new(1));
90 assert_eq!(a.doc_id.as_deref(), Some("doc-001"));
91 assert_eq!(a.pages.len(), 2);
92 }
93
94 #[test]
95 fn test_annotations_to_xml_string() {
96 let a = Annotations::new()
97 .doc_id("doc-abc")
98 .add_page(AnnPage::new(0));
99 let xml = a.to_xml_string();
100 assert!(xml.contains(r#"<?xml version="1.0""#));
101 assert!(xml.contains("ofd:Annotations"));
102 assert!(xml.contains(r#"DocID="doc-abc""#));
103 assert!(xml.contains(r#"PageIndex="0""#));
104 assert!(xml.contains("</ofd:Annotations>"));
105 }
106
107 #[test]
108 fn test_annotations_to_xml_string_no_doc_id() {
109 let a = Annotations::new();
110 let xml = a.to_xml_string();
111 assert!(!xml.contains("DocID"));
112 assert!(xml.contains("</ofd:Annotations>"));
113 }
114
115 #[test]
116 fn test_annotations_clone_debug() {
117 let a = Annotations::new().doc_id("x");
118 let a2 = a.clone();
119 assert_eq!(a2.doc_id.as_deref(), Some("x"));
120 assert!(format!("{a:?}").contains("Annotations"));
121 }
122}