1#[derive(Debug, Clone, Default)]
4pub struct Metadata {
5 entries: Vec<(String, String)>,
6}
7
8impl Metadata {
9 pub fn new() -> Self {
10 Self {
11 entries: Vec::new(),
12 }
13 }
14
15 pub fn set(&mut self, key: impl Into<String>, value: impl Into<String>) {
18 let key = key.into();
19 let value = value.into();
20 if let Some(entry) = self
21 .entries
22 .iter_mut()
23 .find(|(k, _)| k.eq_ignore_ascii_case(&key))
24 {
25 entry.1 = value;
26 } else {
27 self.entries.push((key, value));
28 }
29 }
30
31 pub fn get(&self, key: &str) -> Option<&str> {
33 self.entries
34 .iter()
35 .find(|(k, _)| k.eq_ignore_ascii_case(key))
36 .map(|(_, v)| v.as_str())
37 }
38
39 pub fn remove(&mut self, key: &str) -> Option<String> {
41 if let Some(pos) = self
42 .entries
43 .iter()
44 .position(|(k, _)| k.eq_ignore_ascii_case(key))
45 {
46 Some(self.entries.remove(pos).1)
47 } else {
48 None
49 }
50 }
51
52 pub fn iter(&self) -> impl Iterator<Item = (&str, &str)> {
54 self.entries.iter().map(|(k, v)| (k.as_str(), v.as_str()))
55 }
56
57 pub fn len(&self) -> usize {
59 self.entries.len()
60 }
61
62 pub fn is_empty(&self) -> bool {
64 self.entries.is_empty()
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn test_metadata_basic() {
74 let mut m = Metadata::new();
75 m.set("title", "Test Video");
76 m.set("artist", "Wedeo");
77 assert_eq!(m.get("title"), Some("Test Video"));
78 assert_eq!(m.get("TITLE"), Some("Test Video")); assert_eq!(m.len(), 2);
80 }
81
82 #[test]
83 fn test_metadata_overwrite() {
84 let mut m = Metadata::new();
85 m.set("title", "First");
86 m.set("TITLE", "Second"); assert_eq!(m.get("title"), Some("Second"));
88 assert_eq!(m.len(), 1);
89 }
90
91 #[test]
92 fn test_metadata_order() {
93 let mut m = Metadata::new();
94 m.set("b", "2");
95 m.set("a", "1");
96 m.set("c", "3");
97 let keys: Vec<&str> = m.iter().map(|(k, _)| k).collect();
98 assert_eq!(keys, vec!["b", "a", "c"]); }
100
101 #[test]
102 fn test_metadata_remove() {
103 let mut m = Metadata::new();
104 m.set("key", "value");
105 assert_eq!(m.remove("KEY"), Some("value".to_string()));
106 assert!(m.is_empty());
107 }
108}