Hello, basically here is a link to othe playground : Rust Playground
#![allow(unused)]
use std::collections::HashMap;
#[derive(PartialEq, Debug)]
pub struct Tag {
pub name: String,
pub attributes: HashMap<String, String>
}
pub fn tag_name_predicate(name: String) -> impl Fn(&Tag) -> bool {
move |tag: &Tag| tag.name == name
}
pub fn id_predicate(id: String) -> impl Fn(&Tag) -> bool {
move |tag: &Tag| {
if let Some(actual_id) = tag.attributes.get(&"id".to_string()) {
return *actual_id == id;
}
false
}
}
pub fn and_predicate(predicates: Vec<impl Fn(&Tag) -> bool>) -> impl Fn(&Tag) -> bool {
move |tag: &Tag| {
predicates
.iter()
.fold(true, |acc, predicate| acc && predicate(&tag))
}
}
fn main() {
let mut map = HashMap::new();
map.insert("id".to_string(), "foo".to_string());
let tag = Tag {
name: String::from("div"),
attributes: map,
};
let tag_name_matcher = tag_name_predicate(String::from("div"));
let id_matcher = id_predicate(String::from("foo"));
let matcher = and_predicate(vec![tag_name_matcher, id_matcher]);
let does_match = matcher(&tag);
assert!(does_match);
}
combining 2 predicates is rejected at compile time with the error
error[E0308]: mismatched types
--> src/main.rs:42:56
|
14 | pub fn id_predicate(id: String) -> impl Fn(&Tag) -> bool {
| --------------------- the found opaque type
...
42 | let matcher = and_predicate(vec![tag_name_matcher, id_matcher]);
| ^^^^^^^^^^ expected opaque type, found a different opaque type
|
= note: expected type `impl for<'r> Fn<(&'r Tag,)>` (opaque type at <src/main.rs:10:44>)
found opaque type `impl for<'r> Fn<(&'r Tag,)>` (opaque type at <src/main.rs:14:36>)
= note: distinct uses of `impl Trait` result in different opaque types
Please advise