Skip to content

Commit c496c0b

Browse files
Merge pull request askama-rs#346 from Kijewski/pr-more-values
Implement `Values` for all collection types
2 parents e948374 + e4f0147 commit c496c0b

File tree

1 file changed

+104
-22
lines changed

1 file changed

+104
-22
lines changed

rinja/src/values.rs

+104-22
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ where
6666
{
6767
#[inline]
6868
fn get_value<'a>(&'a self, key: &str) -> Option<&'a dyn Any> {
69-
self.as_slice().get_value(key)
69+
find_value_linear(self.iter(), key)
7070
}
7171
}
7272

@@ -76,13 +76,58 @@ where
7676
V: Value,
7777
{
7878
fn get_value<'a>(&'a self, key: &str) -> Option<&'a dyn Any> {
79-
for (k, v) in self {
80-
if k.borrow() == key {
81-
return v.ref_any();
82-
}
79+
find_value_linear(self.iter(), key)
80+
}
81+
}
82+
83+
#[cfg(feature = "alloc")]
84+
impl<K, V> Values for alloc::vec::Vec<(K, V)>
85+
where
86+
K: Borrow<str>,
87+
V: Value,
88+
{
89+
#[inline]
90+
fn get_value<'a>(&'a self, key: &str) -> Option<&'a dyn Any> {
91+
find_value_linear(self.iter(), key)
92+
}
93+
}
94+
95+
#[cfg(feature = "alloc")]
96+
impl<K, V> Values for alloc::collections::VecDeque<(K, V)>
97+
where
98+
K: Borrow<str>,
99+
V: Value,
100+
{
101+
#[inline]
102+
fn get_value<'a>(&'a self, key: &str) -> Option<&'a dyn Any> {
103+
find_value_linear(self.iter(), key)
104+
}
105+
}
106+
107+
#[cfg(feature = "alloc")]
108+
impl<K, V> Values for alloc::collections::LinkedList<(K, V)>
109+
where
110+
K: Borrow<str>,
111+
V: Value,
112+
{
113+
#[inline]
114+
fn get_value<'a>(&'a self, key: &str) -> Option<&'a dyn Any> {
115+
find_value_linear(self.iter(), key)
116+
}
117+
}
118+
119+
fn find_value_linear<'a, K, V, I>(it: I, key: &str) -> Option<&'a dyn Any>
120+
where
121+
K: Borrow<str> + 'a,
122+
V: Value + 'a,
123+
I: Iterator<Item = &'a (K, V)>,
124+
{
125+
for (k, v) in it {
126+
if k.borrow() == key {
127+
return v.ref_any();
83128
}
84-
None
85129
}
130+
None
86131
}
87132

88133
#[cfg(feature = "alloc")]
@@ -148,6 +193,22 @@ mod tests {
148193

149194
use super::*;
150195

196+
#[track_caller]
197+
fn assert_a_10_c_blam(values: &dyn Values) {
198+
assert_matches!(get_value::<u32>(values, "a"), Ok(10u32));
199+
assert_matches!(get_value::<&str>(values, "c"), Ok(&"blam"));
200+
assert_matches!(get_value::<u8>(values, "a"), Err(Error::ValueType));
201+
assert_matches!(get_value::<u8>(values, "d"), Err(Error::ValueMissing));
202+
}
203+
204+
#[track_caller]
205+
fn assert_a_12_c_blam(values: &dyn Values) {
206+
assert_matches!(get_value::<u32>(values, "a"), Ok(12u32));
207+
assert_matches!(get_value::<&str>(values, "c"), Ok(&"blam"));
208+
assert_matches!(get_value::<u8>(values, "a"), Err(Error::ValueType));
209+
assert_matches!(get_value::<u8>(values, "d"), Err(Error::ValueMissing));
210+
}
211+
151212
#[cfg(feature = "std")]
152213
#[test]
153214
fn values_on_hashmap() {
@@ -156,12 +217,9 @@ mod tests {
156217
use std::collections::HashMap;
157218

158219
let mut values: HashMap<String, Box<dyn Any>> = HashMap::new();
159-
values.insert("a".into(), Box::new(10u32));
220+
values.insert("a".into(), Box::new(12u32));
160221
values.insert("c".into(), Box::new("blam"));
161-
assert_matches!(get_value::<u32>(&values, "a"), Ok(&10u32));
162-
assert_matches!(get_value::<&str>(&values, "c"), Ok(&"blam"));
163-
assert_matches!(get_value::<u8>(&values, "a"), Err(Error::ValueType));
164-
assert_matches!(get_value::<u8>(&values, "d"), Err(Error::ValueMissing));
222+
assert_a_12_c_blam(&values);
165223

166224
let mut values: HashMap<&str, Box<dyn Any>> = HashMap::new();
167225
values.insert("a", Box::new(10u32));
@@ -176,13 +234,9 @@ mod tests {
176234
use alloc::string::String;
177235

178236
let mut values: BTreeMap<String, Box<dyn Any>> = BTreeMap::new();
179-
values.insert("a".into(), Box::new(10u32));
237+
values.insert("a".into(), Box::new(12u32));
180238
values.insert("c".into(), Box::new("blam"));
181-
182-
assert_matches!(get_value::<u32>(&values, "a"), Ok(&10u32));
183-
assert_matches!(get_value::<&str>(&values, "c"), Ok(&"blam"));
184-
assert_matches!(get_value::<u8>(&values, "a"), Err(Error::ValueType));
185-
assert_matches!(get_value::<u8>(&values, "d"), Err(Error::ValueMissing));
239+
assert_a_12_c_blam(&values);
186240

187241
let mut values: BTreeMap<&str, Box<dyn Any>> = BTreeMap::new();
188242
values.insert("a", Box::new(10u32));
@@ -191,10 +245,38 @@ mod tests {
191245

192246
#[test]
193247
fn values_on_slice() {
194-
let values: &[(&str, &dyn Any)] = &[("a", &12u32), ("c", &"blam")];
195-
assert_matches!(get_value::<u32>(&values, "a"), Ok(12u32));
196-
assert_matches!(get_value::<&str>(&values, "c"), Ok(&"blam"));
197-
assert_matches!(get_value::<u8>(&values, "a"), Err(Error::ValueType));
198-
assert_matches!(get_value::<u8>(&values, "d"), Err(Error::ValueMissing));
248+
let slice: &[(&str, &dyn Any)] = &[("a", &12u32), ("c", &"blam")];
249+
assert_a_12_c_blam(&slice);
250+
}
251+
252+
#[cfg(feature = "alloc")]
253+
#[test]
254+
fn values_vec() {
255+
let vec: alloc::vec::Vec<(&str, &dyn Any)> = alloc::vec![("a", &12u32), ("c", &"blam")];
256+
assert_a_12_c_blam(&vec);
257+
}
258+
259+
#[cfg(feature = "alloc")]
260+
#[test]
261+
fn values_deque() {
262+
let mut deque = alloc::collections::VecDeque::<(&str, &dyn Any)>::new();
263+
deque.push_back(("a", &12u32));
264+
deque.push_back(("c", &"blam"));
265+
assert_a_12_c_blam(&deque);
266+
deque.pop_front();
267+
deque.push_back(("a", &10u32));
268+
assert_a_10_c_blam(&deque);
269+
}
270+
271+
#[cfg(feature = "alloc")]
272+
#[test]
273+
fn values_list() {
274+
let mut list = alloc::collections::LinkedList::<(&str, &dyn Any)>::new();
275+
list.push_back(("a", &12u32));
276+
list.push_back(("c", &"blam"));
277+
assert_a_12_c_blam(&list);
278+
list.pop_front();
279+
list.push_back(("a", &10u32));
280+
assert_a_10_c_blam(&list);
199281
}
200282
}

0 commit comments

Comments
 (0)