Simple tool for automatic file management
1// SPDX-FileCopyrightText: 2024 Łukasz Niemier <#@hauleth.dev>
2//
3// SPDX-License-Identifier: EUPL-1.2
4
5use std::fmt;
6use std::path::Path;
7
8use serde::{de, Deserialize};
9use wildmatch::WildMatch;
10
11/// Patterns that can be matched against files
12#[derive(Debug, Deserialize)]
13#[serde(rename_all = "snake_case")]
14pub enum Pattern {
15 #[serde(deserialize_with = "deserialize_wildcard")]
16 Wildcard(WildMatch),
17 #[serde(deserialize_with = "deserialize_regex")]
18 Regex(regex::Regex),
19 Exact(Box<Path>),
20}
21
22impl Pattern {
23 pub fn matches(&self, path: &Path) -> bool {
24 match *self {
25 Self::Wildcard(ref pattern) => pattern.matches(path.to_str().unwrap()),
26 Self::Regex(ref pattern) => pattern.is_match(path.to_str().unwrap()),
27 Self::Exact(ref pattern) => **pattern == *path,
28 }
29 }
30}
31
32struct RegexVisitor;
33
34impl<'de> de::Visitor<'de> for RegexVisitor {
35 type Value = regex::Regex;
36
37 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
38 write!(formatter, "expected regex string")
39 }
40
41 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
42 where
43 E: de::Error,
44 {
45 match regex::Regex::new(s) {
46 Ok(regex) => Ok(regex),
47 Err(regex::Error::Syntax(ref desc)) => {
48 Err(E::invalid_value(de::Unexpected::Str(s), &desc.as_str()))
49 }
50 Err(_) => unreachable!(),
51 }
52 }
53}
54
55fn deserialize_regex<'de, D>(des: D) -> Result<regex::Regex, D::Error>
56where
57 D: serde::Deserializer<'de>,
58{
59 des.deserialize_str(RegexVisitor)
60}
61
62struct WildcardVisitor;
63
64impl<'de> de::Visitor<'de> for WildcardVisitor {
65 type Value = WildMatch;
66
67 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
68 write!(formatter, "expected regex string")
69 }
70
71 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
72 where
73 E: de::Error,
74 {
75 Ok(WildMatch::new(s))
76 }
77}
78
79fn deserialize_wildcard<'de, D>(des: D) -> Result<WildMatch, D::Error>
80where
81 D: serde::Deserializer<'de>,
82{
83 des.deserialize_str(WildcardVisitor)
84}