nom_exif/exif/
png_text.rs1#[derive(Debug, Clone, Default)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23pub struct PngTextChunks {
24 pub(crate) entries: Vec<(String, String)>,
25}
26
27impl PngTextChunks {
28 pub fn get(&self, key: &str) -> Option<&str> {
30 self.entries
31 .iter()
32 .find(|(k, _)| k == key)
33 .map(|(_, v)| v.as_str())
34 }
35
36 pub fn get_all<'a>(&'a self, key: &'a str) -> impl Iterator<Item = &'a str> + 'a {
38 self.entries
39 .iter()
40 .filter(move |(k, _)| k == key)
41 .map(|(_, v)| v.as_str())
42 }
43
44 pub fn iter(&self) -> impl Iterator<Item = (&str, &str)> + '_ {
46 self.entries.iter().map(|(k, v)| (k.as_str(), v.as_str()))
47 }
48
49 pub fn len(&self) -> usize {
51 self.entries.len()
52 }
53
54 pub fn is_empty(&self) -> bool {
56 self.entries.is_empty()
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 fn fixture() -> PngTextChunks {
65 PngTextChunks {
66 entries: vec![
67 ("Title".into(), "Hello".into()),
68 ("Author".into(), "Alice".into()),
69 ("Comment".into(), "first comment".into()),
70 ("Comment".into(), "second comment".into()),
71 ],
72 }
73 }
74
75 #[test]
76 fn get_returns_first_match() {
77 let t = fixture();
78 assert_eq!(t.get("Title"), Some("Hello"));
79 assert_eq!(t.get("Comment"), Some("first comment"));
80 assert_eq!(t.get("nonexistent"), None);
81 }
82
83 #[test]
84 fn get_all_returns_all_in_order() {
85 let t = fixture();
86 let comments: Vec<&str> = t.get_all("Comment").collect();
87 assert_eq!(comments, vec!["first comment", "second comment"]);
88 let titles: Vec<&str> = t.get_all("Title").collect();
89 assert_eq!(titles, vec!["Hello"]);
90 let nothing: Vec<&str> = t.get_all("nonexistent").collect();
91 assert!(nothing.is_empty());
92 }
93
94 #[test]
95 fn iter_in_file_order_with_duplicates() {
96 let t = fixture();
97 let pairs: Vec<(&str, &str)> = t.iter().collect();
98 assert_eq!(pairs.len(), 4);
99 assert_eq!(pairs[2], ("Comment", "first comment"));
100 assert_eq!(pairs[3], ("Comment", "second comment"));
101 }
102
103 #[test]
104 fn len_and_is_empty() {
105 let t = fixture();
106 assert_eq!(t.len(), 4);
107 assert!(!t.is_empty());
108
109 let empty = PngTextChunks::default();
110 assert_eq!(empty.len(), 0);
111 assert!(empty.is_empty());
112 }
113}