mas_i18n/sprintf/
argument.rs1use std::collections::HashMap;
8
9use serde_json::Value;
10
11#[derive(Debug, Clone, Default)]
13pub struct List {
14 arguments: Vec<Value>,
15 name_index: HashMap<String, usize>,
16}
17
18impl List {
19 #[must_use]
21 pub fn get_by_index(&self, index: usize) -> Option<&Value> {
22 self.arguments.get(index)
23 }
24
25 #[must_use]
27 pub fn get_by_name(&self, name: &str) -> Option<&Value> {
28 self.name_index
29 .get(name)
30 .and_then(|index| self.get_by_index(*index))
31 }
32}
33
34impl<A: Into<Argument>> FromIterator<A> for List {
35 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
36 let mut arguments = Vec::new();
37 let mut name_index = HashMap::new();
38
39 for (index, argument) in iter.into_iter().enumerate() {
40 let argument = argument.into();
41 if let Some(name) = argument.name {
42 name_index.insert(name.clone(), index);
43 }
44
45 arguments.push(argument.value);
46 }
47
48 Self {
49 arguments,
50 name_index,
51 }
52 }
53}
54
55pub struct Argument {
57 name: Option<String>,
58 value: Value,
59}
60
61impl From<Value> for Argument {
62 fn from(value: Value) -> Self {
63 Self { name: None, value }
64 }
65}
66
67impl From<(&str, Value)> for Argument {
68 fn from((name, value): (&str, Value)) -> Self {
69 Self {
70 name: Some(name.to_owned()),
71 value,
72 }
73 }
74}
75
76impl From<(String, Value)> for Argument {
77 fn from((name, value): (String, Value)) -> Self {
78 Self {
79 name: Some(name),
80 value,
81 }
82 }
83}
84
85impl Argument {
86 #[must_use]
88 pub fn named(name: String, value: Value) -> Self {
89 Self {
90 name: Some(name),
91 value,
92 }
93 }
94
95 #[must_use]
97 pub fn with_name(mut self, name: String) -> Self {
98 self.name = Some(name);
99 self
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use serde_json::json;
106
107 use super::*;
108
109 #[test]
110 fn test_argument_list() {
111 let list = List::from_iter([
112 ("hello", json!("world")),
113 ("alice", json!(null)),
114 ("bob", json!(42)),
115 ]);
116
117 assert_eq!(list.get_by_index(0), Some(&json!("world")));
118 assert_eq!(list.get_by_index(1), Some(&json!(null)));
119 assert_eq!(list.get_by_index(2), Some(&json!(42)));
120 assert_eq!(list.get_by_index(3), None);
121
122 assert_eq!(list.get_by_name("hello"), Some(&json!("world")));
123 assert_eq!(list.get_by_name("alice"), Some(&json!(null)));
124 assert_eq!(list.get_by_name("bob"), Some(&json!(42)));
125 assert_eq!(list.get_by_name("charlie"), None);
126
127 let list = List::from_iter([
128 Argument::from(json!("hello")),
129 Argument::named("alice".to_owned(), json!(null)),
130 Argument::named("bob".to_owned(), json!(42)),
131 ]);
132
133 assert_eq!(list.get_by_index(0), Some(&json!("hello")));
134 assert_eq!(list.get_by_index(1), Some(&json!(null)));
135 assert_eq!(list.get_by_index(2), Some(&json!(42)));
136 assert_eq!(list.get_by_index(3), None);
137
138 assert_eq!(list.get_by_name("hello"), None);
139 assert_eq!(list.get_by_name("alice"), Some(&json!(null)));
140 assert_eq!(list.get_by_name("bob"), Some(&json!(42)));
141 assert_eq!(list.get_by_name("charlie"), None);
142 }
143}