1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use std::{fmt, str::FromStr};
use crate::keyval::KeyVal;
/// The data structure [Element] used by all variants internally.
pub struct Element {
pub text: String,
pub args: Vec<KeyVal>,
}
impl Element {
/// Constructs a new [Element] with [Element::text].
/// [Element::args] will be an empty vector.
pub fn new(text: String) -> Element {
Element {
text,
args: Vec::new(),
}
}
/// Find an entry in [Element::args] with a matching [KeyVal::key] and
/// update its [KeyVal::val] field. If no such matching [KeyVal] is found
/// or if the keyval [kv] is nameless, then simply inserts [kv] into the
/// back of [Element::args].
///
/// See [KeyVal::is_nameless].
pub fn upsert(&mut self, kv: KeyVal) {
// We cannot update nameless keyvals, so we insert as-is.
if kv.is_nameless() {
self.args.push(kv);
return;
}
if let Some(prev) = self.args.iter().position(|arg| match &arg.key {
None => false,
Some(k) => k == kv.key.as_ref().unwrap(),
}) {
self.args[prev].val = kv.val;
return;
}
// Else, there was no match.
// Insert new keyval.
self.args.push(kv);
}
/// Returns true if there is a [KeyVal] in [Element::args] which has
/// an identical [KeyVal::key] field as the input [key].
/// Nameless keyvals will never match and always return false.
pub fn has_key(&self, key: &str) -> bool {
if let Some(_) = self.args.iter().position(|arg| match &arg.key {
None => false,
Some(k) => k == key,
}) {
return true;
}
false
}
/// Tests every key [String] in [keys] with [Element::has_key].
/// If and only if they are all found, then this returns true.
/// If any key fails, then this returns false.
pub fn has_keys(&self, keys: &Vec<&str>) -> bool {
for iter in keys.into_iter() {
if !self.has_key(iter) {
return false;
}
}
return true;
}
/// Finds the matching [KeyVal] whose [KeyVal::key] field is [key] and
/// returns the [KeyVal::val] value coerced into type [T] as [Some].
///
/// If no such key is found, or the value could not be coerced into [T],
/// then [None] is returned.
pub fn get_key_value<T>(&self, key: &str) -> Option<T>
where
T: FromStr,
{
if let Some(idx) = self.args.iter().position(|kv| match &kv.key {
None => false,
Some(k) => k == key,
}) {
return match self.args[idx].val.parse::<T>() {
Ok(t) => Some(t),
Err(_) => None,
};
}
None
}
/// A variation of [Element::get_key_value] which accepts an explicit [or]
/// input value of type [T]. If the former method would return [None], then
/// this method returns [or].
pub fn get_key_value_or<T>(&self, key: &str, or: T) -> T
where
T: FromStr,
{
if let Some(idx) = self.args.iter().position(|kv| match &kv.key {
None => false,
Some(k) => k == key,
}) {
return match self.args[idx].val.parse::<T>() {
Ok(t) => t,
Err(_) => or,
};
}
or
}
}
impl fmt::Display for Element {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} args={{{}}}", self.text, self.args.iter().map(|a| a.to_string()).collect::<Vec<String>>().join(", "))
}
}