microformats_types/
traits.rs1use crate::{Document, Item, PropertyValue};
4use std::collections::HashSet;
5
6pub trait LanguageFilter: Sized {
8 fn matches_languages(&self, languages: &HashSet<&str>) -> bool;
10
11 fn filter_by_languages_set(&self, languages: &HashSet<&str>) -> Option<Self>;
13}
14
15pub trait FindItemByProperty {
17 fn find_items_with_matching_property_value_by<F>(&self, predicate: F) -> Vec<(String, Item)>
19 where
20 F: Fn(String, PropertyValue) -> bool + Copy;
21
22 fn find_items_with_matching_property_value(
24 &self,
25 needle: PropertyValue,
26 ) -> Vec<(String, Item)> {
27 self.find_items_with_matching_property_value_by(|_name, property_value| {
28 property_value == needle
29 })
30 }
31}
32
33impl FindItemByProperty for Item {
34 fn find_items_with_matching_property_value_by<F>(&self, predicate: F) -> Vec<(String, Item)>
35 where
36 F: Fn(String, PropertyValue) -> bool + Copy,
37 {
38 let mut values = self
39 .properties
40 .iter()
41 .filter_map(|(name, values)| {
42 if values
43 .iter()
44 .any(|value| predicate(name.to_owned(), value.to_owned()))
45 {
46 Some((name.to_owned(), self.to_owned()))
47 } else {
48 None
49 }
50 })
51 .collect::<Vec<_>>();
52
53 self.children.iter().for_each(|child| {
54 values.extend(child.find_items_with_matching_property_value_by(predicate));
55 });
56
57 values
58 }
59}
60
61impl FindItemByProperty for Document {
62 fn find_items_with_matching_property_value_by<F>(&self, predicate: F) -> Vec<(String, Item)>
63 where
64 F: Fn(String, PropertyValue) -> bool + std::marker::Copy,
65 {
66 self.items
67 .iter()
68 .flat_map(|item| item.find_items_with_matching_property_value_by(predicate))
69 .collect()
70 }
71}
72
73pub trait FindItemByUrl: FindItemByProperty {
75 fn find_item_by_url(&self, expected_url: &url::Url) -> Option<Item> {
77 let url_property_value = PropertyValue::Url(crate::UrlValue::new(expected_url.to_owned()));
78 self.find_items_with_matching_property_value(url_property_value)
79 .first()
80 .map(|(_name, value)| value.to_owned())
81 }
82}
83
84impl FindItemByUrl for Document {}
85
86impl FindItemByUrl for Item {}
87
88pub trait FindItemById {
90 fn find_item_by_id(&self, expected_id: &str) -> Option<Item>;
92}
93
94impl FindItemById for Item {
95 fn find_item_by_id(&self, expected_id: &str) -> Option<Item> {
96 if self.id == Some(expected_id.to_string()) {
97 Some(self.to_owned())
98 } else {
99 self.children
100 .iter()
101 .find_map(|item| item.find_item_by_id(expected_id))
102 }
103 }
104}
105
106impl FindItemById for Document {
107 fn find_item_by_id(&self, expected_id: &str) -> Option<Item> {
108 self.items
109 .iter()
110 .find_map(|item| item.find_item_by_id(expected_id))
111 }
112}