Simple tool for automatic file management
at master 2.1 kB view raw
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}