chanoma/modifier/
character_eliminator.rs

1use super::{ModifiedRecord, Modifier};
2use crate::error::Error;
3use crate::modifier::ModifierFromYamlValue;
4use crate::modifier_kind::ModifierKind;
5use crate::position::Position;
6use std::collections::HashSet;
7use std::str::FromStr;
8
9// 文字を削除する
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct CharacterEliminator {
12    chars: HashSet<char>,
13}
14
15impl Modifier for CharacterEliminator {
16    fn modify(&self, input: &str) -> String {
17        let mut s = Vec::new();
18        for c in input.chars() {
19            if self.chars.get(&c).is_some() {
20                // noop
21            } else {
22                s.push(c);
23            }
24        }
25        s.into_iter().collect::<String>()
26    }
27
28    fn modify_with_positions(&self, input: &str) -> ModifiedRecord {
29        let positions: Vec<Position> = vec![];
30        ModifiedRecord::new(
31            ModifierKind::CharacterEliminator(self.clone()),
32            self.modify(input),
33            positions,
34        )
35    }
36}
37
38impl ModifierFromYamlValue for CharacterEliminator {
39    fn from_yaml_value(value: &serde_yaml::Value) -> Result<Self, Error> {
40        let map = value
41            .as_sequence()
42            .unwrap()
43            .iter()
44            .map(|v| v.as_str().unwrap().chars().next().unwrap())
45            .collect::<Vec<char>>();
46        Ok(Self::from_chars(map))
47    }
48}
49
50impl FromStr for CharacterEliminator {
51    type Err = Error;
52    fn from_str(s: &str) -> Result<Self, Self::Err> {
53        let chars = s
54            .split(',')
55            .into_iter()
56            .filter_map(|st| st.trim().to_string().chars().next())
57            .collect::<Vec<char>>();
58        if chars.is_empty() {
59            return Err(Error::ModifierKindParseError("require value.".to_string()));
60        }
61        Ok(Self::from_chars(chars))
62    }
63}
64
65impl From<CharacterEliminator> for ModifierKind {
66    fn from(m: CharacterEliminator) -> ModifierKind {
67        ModifierKind::CharacterEliminator(m)
68    }
69}
70
71impl CharacterEliminator {
72    #[allow(dead_code)]
73    pub fn from_char(c: char) -> Self {
74        let mut chars = HashSet::new();
75        chars.insert(c);
76        Self { chars }
77    }
78
79    pub fn from_chars(chs: Vec<char>) -> Self {
80        let mut chars = HashSet::new();
81        for c in chs.into_iter() {
82            chars.insert(c);
83        }
84        Self { chars }
85    }
86}
87
88/// character_eliminator!['a', 'b'};
89#[macro_export]
90macro_rules! character_eliminator {
91    ($($c:expr),*) => {{
92        let mut ch = Vec::new();
93        $(
94            ch.push($c);
95        )*
96        crate::modifier::character_eliminator::CharacterEliminator::from_chars(ch)
97    }};
98}