chanoma/modifier/
character_eliminator.rs1use 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#[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 } 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#[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}