1use std::{collections::BTreeSet, fmt, ops::Deref, path::Path, str::FromStr};
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub struct Pattern(glob::Pattern);
8impl fmt::Display for Pattern {
9 #[inline]
10 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11 fmt::Display::fmt(&self.0, f)
12 }
13}
14impl FromStr for Pattern {
15 type Err = <glob::Pattern as FromStr>::Err;
16
17 #[inline]
18 fn from_str(s: &str) -> Result<Self, Self::Err> {
19 s.parse().map(Self)
20 }
21}
22impl Deref for Pattern {
23 type Target = glob::Pattern;
24
25 #[inline(always)]
26 fn deref(&self) -> &Self::Target {
27 &self.0
28 }
29}
30impl Serialize for Pattern {
31 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
32 where
33 S: Serializer,
34 {
35 serializer.serialize_str(self.as_str())
36 }
37}
38impl<'de> Deserialize<'de> for Pattern {
39 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
40 where
41 D: Deserializer<'de>,
42 {
43 use serde::de::Visitor;
44
45 struct PatternVisitor;
46 impl<'de> Visitor<'de> for PatternVisitor {
47 type Value = Pattern;
48
49 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
50 formatter.write_str("a valid glob pattern")
51 }
52
53 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
54 where
55 E: serde::de::Error,
56 {
57 s.parse::<Pattern>().map_err(serde::de::Error::custom)
58 }
59 }
60
61 deserializer.deserialize_str(PatternVisitor)
62 }
63}
64
65#[derive(Default, Debug, Clone, Serialize, Deserialize)]
67pub struct PatternSet(BTreeSet<Pattern>);
68impl PatternSet {
69 pub fn is_empty(&self) -> bool {
71 self.0.is_empty()
72 }
73
74 pub fn iter(&self) -> impl Iterator<Item = &Pattern> + '_ {
75 self.0.iter()
76 }
77
78 pub fn matches(&self, s: &str) -> bool {
80 self.0.iter().any(|pattern| pattern.matches(s))
81 }
82
83 pub fn matches_path(&self, path: &Path) -> bool {
85 self.0.iter().any(|pattern| pattern.matches_path(path))
86 }
87}
88impl FromIterator<Pattern> for PatternSet {
89 fn from_iter<T>(iter: T) -> Self
90 where
91 T: IntoIterator<Item = Pattern>,
92 {
93 Self(iter.into_iter().collect())
94 }
95}
96impl<'a> FromIterator<&'a Pattern> for PatternSet {
97 fn from_iter<T>(iter: T) -> Self
98 where
99 T: IntoIterator<Item = &'a Pattern>,
100 {
101 Self(iter.into_iter().cloned().collect())
102 }
103}