mirror of
https://github.com/askama-rs/askama.git
synced 2025-09-29 22:11:17 +00:00
Fix unique
filter implementation
This commit is contained in:
parent
7fccbdf1d7
commit
a5b43c0aa2
@ -1,3 +1,4 @@
|
|||||||
|
use core::convert::Infallible;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
@ -9,8 +10,7 @@ use std::rc::Rc;
|
|||||||
/// the data is wrapped inside `Rc`.
|
/// the data is wrapped inside `Rc`.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #[cfg(feature = "code-in-doc")] {
|
/// # use askama::Template;
|
||||||
/// # use askama::{Template, filters};
|
|
||||||
/// #[derive(Template)]
|
/// #[derive(Template)]
|
||||||
/// #[template(ext = "html", source = "{% for elem in example|unique %}{{ elem }},{% endfor %}")]
|
/// #[template(ext = "html", source = "{% for elem in example|unique %}{{ elem }},{% endfor %}")]
|
||||||
/// struct Example<'a> {
|
/// struct Example<'a> {
|
||||||
@ -19,14 +19,15 @@ use std::rc::Rc;
|
|||||||
///
|
///
|
||||||
/// assert_eq!(
|
/// assert_eq!(
|
||||||
/// Example { example: vec!["a", "b", "a", "c"] }.to_string(),
|
/// Example { example: vec!["a", "b", "a", "c"] }.to_string(),
|
||||||
/// "a,b,c"
|
/// "a,b,c,"
|
||||||
/// );
|
/// );
|
||||||
/// # }
|
|
||||||
/// ```
|
/// ```
|
||||||
pub fn unique<T: Hash + Eq>(it: impl IntoIterator<Item = T>) -> impl Iterator<Item = Rc<T>> {
|
pub fn unique<T: Hash + Eq>(
|
||||||
|
it: impl IntoIterator<Item = T>,
|
||||||
|
) -> Result<impl Iterator<Item = Rc<T>>, Infallible> {
|
||||||
let mut set = HashMap::new();
|
let mut set = HashMap::new();
|
||||||
|
|
||||||
it.into_iter().filter_map(move |elem| {
|
Ok(it.into_iter().filter_map(move |elem| {
|
||||||
// To prevent cloning the data, we need to use `Rc`, like that we can clone `elem` as
|
// To prevent cloning the data, we need to use `Rc`, like that we can clone `elem` as
|
||||||
// key of the `HashSet` and return it.
|
// key of the `HashSet` and return it.
|
||||||
if let Entry::Vacant(entry) = set.entry(Rc::new(elem)) {
|
if let Entry::Vacant(entry) = set.entry(Rc::new(elem)) {
|
||||||
@ -34,7 +35,7 @@ pub fn unique<T: Hash + Eq>(it: impl IntoIterator<Item = T>) -> impl Iterator<It
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -47,15 +48,15 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_unique() {
|
fn test_unique() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unique(["a", "b", "a", "c"]).collect::<Vec<_>>(),
|
unique(["a", "b", "a", "c"]).unwrap().collect::<Vec<_>>(),
|
||||||
vec![Rc::new("a"), Rc::new("b"), Rc::new("c")]
|
vec![Rc::new("a"), Rc::new("b"), Rc::new("c")]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unique([1, 1, 1, 2, 1]).collect::<Vec<_>>(),
|
unique([1, 1, 1, 2, 1]).unwrap().collect::<Vec<_>>(),
|
||||||
vec![Rc::new(1), Rc::new(2)]
|
vec![Rc::new(1), Rc::new(2)]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unique("hello".chars()).collect::<Vec<_>>(),
|
unique("hello".chars()).unwrap().collect::<Vec<_>>(),
|
||||||
vec![Rc::new('h'), Rc::new('e'), Rc::new('l'), Rc::new('o')]
|
vec![Rc::new('h'), Rc::new('e'), Rc::new('l'), Rc::new('o')]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user