viral32111_xml/attributes.rs
1/// Holds the key-value pairs.
2pub struct Attributes {
3 pub map: Vec<(String, String)>,
4}
5
6impl Attributes {
7 /*
8 /// Checks if an attribute exists.
9 pub fn has(&self, name: &str) -> bool {
10 self.map
11 .iter()
12 .any(|(attribute_name, _)| attribute_name.eq(name))
13 }
14 */
15
16 /// Gets the value of an attribute.
17 pub fn get(&self, name: &str) -> Option<String> {
18 self.map.iter().find_map(|(attribute_name, value)| {
19 if attribute_name.eq(name) {
20 return Some(value.to_string());
21 }
22
23 None
24 })
25 }
26
27 /*
28 /// Gets the value of an attribute, ignoring case of the name.
29 pub fn get_case_insensitive(&self, name: &str) -> Option<String> {
30 self.map.iter().find_map(|(attribute_name, value)| {
31 if attribute_name.eq_ignore_ascii_case(name) {
32 return Some(value.to_string());
33 }
34
35 None
36 })
37 }
38 */
39}
40
41/// Parses a string of attributes into a map of key-value pairs.
42pub fn parse(text: &str) -> Attributes {
43 let map = text
44 .split(" ")
45 .filter_map(|attribute| {
46 // Ignore empty attributes
47 if attribute.is_empty() {
48 return None;
49 }
50
51 // Attributes are equals delimited key-value pairs
52 let (name, value) = attribute.split_once("=")?;
53
54 // Ignore attributes with no name
55 if name.is_empty() {
56 return None;
57 }
58
59 // Strip quotes around the value
60 let value = value.trim_matches('"');
61
62 // Ignore attributes with no value
63 if value.is_empty() {
64 return None;
65 }
66
67 Some((name.to_string(), value.to_string()))
68 })
69 .collect();
70
71 Attributes { map }
72}