easyofd_core/signatures/
references.rs1use super::check_method::CheckMethod;
8use super::reference::Reference;
9
10#[derive(Debug, Clone)]
15pub struct References {
16 pub check_method: Option<String>,
19 pub references: Vec<Reference>,
21}
22
23impl References {
24 #[must_use]
26 pub fn new() -> Self {
27 Self {
28 check_method: None,
29 references: Vec::new(),
30 }
31 }
32
33 #[must_use]
35 pub fn check_method(mut self, method: impl Into<String>) -> Self {
36 self.check_method = Some(method.into());
37 self
38 }
39
40 #[must_use]
53 pub fn set_check_method(mut self, method: CheckMethod) -> Self {
54 self.check_method = Some(method.as_str().to_owned());
55 self
56 }
57
58 #[must_use]
60 pub fn check_method_str(&self) -> Option<&str> {
61 self.check_method.as_deref()
62 }
63
64 #[must_use]
75 pub fn check_method_enum(&self) -> Option<CheckMethod> {
76 self.check_method
77 .as_deref()
78 .and_then(|s| CheckMethod::try_from_str(s).ok())
79 }
80
81 #[must_use]
83 pub fn add_reference(mut self, reference: Reference) -> Self {
84 self.references.push(reference);
85 self
86 }
87
88 pub fn has_file(&self, abs_loc: &str) -> bool {
90 self.references.iter().any(|r| r.file_ref == abs_loc)
91 }
92
93 #[must_use]
95 pub fn to_xml_string(&self) -> String {
96 let mut xml = String::from("<ofd:References");
97 if let Some(ref method) = self.check_method {
98 use std::fmt::Write;
99 let _ = write!(xml, r#" CheckMethod="{method}""#);
100 }
101 xml.push('>');
102 for r in &self.references {
103 xml.push('\n');
104 xml.push_str(&r.to_xml_string());
105 }
106 xml.push_str("\n</ofd:References>");
107 xml
108 }
109}
110
111impl Default for References {
112 fn default() -> Self {
113 Self::new()
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_references_new() {
123 let refs = References::new();
124 assert!(refs.check_method.is_none());
125 assert!(refs.references.is_empty());
126 }
127
128 #[test]
129 fn test_references_builder() {
130 let refs = References::new()
131 .check_method("SM3")
132 .add_reference(Reference::new("/Doc_0/Document.xml", "abc"))
133 .add_reference(Reference::new("/Doc_0/Pages/Page_0/Content.xml", "def"));
134 assert_eq!(refs.check_method.as_deref(), Some("SM3"));
135 assert_eq!(refs.references.len(), 2);
136 }
137
138 #[test]
139 fn test_references_has_file() {
140 let refs = References::new().add_reference(Reference::new("/Doc_0/Document.xml", "abc"));
141 assert!(refs.has_file("/Doc_0/Document.xml"));
142 assert!(!refs.has_file("/Doc_0/Other.xml"));
143 }
144
145 #[test]
146 fn test_references_xml() {
147 let refs = References::new()
148 .check_method("SHA256")
149 .add_reference(Reference::new("/Doc_0/Document.xml", "hash1"));
150 let xml = refs.to_xml_string();
151 assert!(xml.contains("CheckMethod=\"SHA256\""));
152 assert!(xml.contains("FileRef=\"/Doc_0/Document.xml\""));
153 assert!(xml.contains("</ofd:References>"));
154 }
155
156 #[test]
157 fn test_references_default() {
158 let refs = References::default();
159 assert!(refs.references.is_empty());
160 }
161
162 #[test]
163 fn test_set_check_method_enum() {
164 let refs = References::new().set_check_method(CheckMethod::Sm3);
165 assert_eq!(refs.check_method.as_deref(), Some("SM3"));
166 assert_eq!(refs.check_method_str(), Some("SM3"));
167 }
168
169 #[test]
170 fn test_check_method_enum_roundtrip() {
171 for method in [
172 CheckMethod::Md5,
173 CheckMethod::Sha1,
174 CheckMethod::Sha256,
175 CheckMethod::Sm3,
176 ] {
177 let refs = References::new().set_check_method(method);
178 assert_eq!(refs.check_method_enum(), Some(method));
179 }
180 }
181
182 #[test]
183 fn test_check_method_enum_none() {
184 let refs = References::new();
185 assert!(refs.check_method_enum().is_none());
186 }
187
188 #[test]
189 fn test_check_method_enum_unknown_string() {
190 let refs = References::new().check_method("UNKNOWN");
191 assert!(refs.check_method_enum().is_none());
192 }
193
194 #[test]
195 fn test_set_check_method_xml_unchanged() {
196 let refs_str = References::new().check_method("SM3");
198 let refs_enum = References::new().set_check_method(CheckMethod::Sm3);
199 assert_eq!(refs_str.to_xml_string(), refs_enum.to_xml_string());
200 }
201}