stfu/
types.rs

1//! Utility types.
2
3/// An alternative filter type that allows general addition of words.
4///
5/// # Usage
6/// ```
7/// use stfu::word_lists::category::SEXUAL_ANATOMY_SEXUAL_ACTS;
8/// use stfu::types::OwnedFilter;
9/// # fn main() {
10/// let mut filter = OwnedFilter::default();
11/// filter.add_slice(&SEXUAL_ANATOMY_SEXUAL_ACTS);
12/// assert_eq!(filter.filter_string("hello world"), None);
13/// assert_eq!(filter.filter_string("Mary had a little fucking lamb"), Some("fucking"));
14/// # }
15pub struct OwnedFilter(Vec<String>);
16
17impl OwnedFilter {
18    /// Creates a new `OwnedFilter` with the given list of words.
19    pub fn new(list: Vec<String>) -> Self {
20        Self(list)
21    }
22
23    /// Creates a empty `OwnedFilter`.
24    pub fn empty() -> Self {
25        Self(Vec::new())
26    }
27
28    /// Adds a word to the filter.
29    pub fn add_word(&mut self, word: String) {
30        self.0.push(word);
31    }
32
33    /// Adds a Vec of words to the filter.
34    pub fn add_vec(&mut self, vec: Vec<String>) {
35        self.0.extend(vec);
36    }
37
38    /// Adds a slice of words to the filter.
39    pub fn add_slice<T: AsRef<str>>(&mut self, slice: &[T]) {
40        self.0.extend(slice.iter().map(|s| s.as_ref().to_string()));
41    }
42
43    /// Returns the list of words.
44    pub fn word_list(&self) -> &[String] {
45        &self.0
46    }
47
48    /// Removes a word from the filter.
49    ///
50    /// Warning: this is an expensive operation. Filter the words you add to the filter, instead.
51    pub fn remove_word(&mut self, word: &str) {
52        self.0.retain(|s| s != word);
53    }
54
55    /// Returns true if the phrase contains a word in the filter.
56    ///
57    /// This simply calls [crate::filter::filter_string], see its docs for more info.
58    pub fn filter_string(&self, s: &str) -> Option<&str> {
59        crate::filter::filter_string(s, &self.0)
60    }
61}
62
63impl AsRef<[String]> for OwnedFilter {
64    fn as_ref(&self) -> &[String] {
65        self.word_list()
66    }
67}
68
69impl Default for OwnedFilter {
70    fn default() -> Self {
71        Self::empty()
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78
79    #[test]
80    fn check_owned_filter() {
81        let mut filter = OwnedFilter::empty();
82        filter.add_word("hello".to_string());
83        filter.add_vec(vec![
84            "world".to_string(),
85            "this".to_string(),
86            "is".to_string(),
87        ]);
88        filter.add_slice(&["a", "test"]);
89        assert_eq!(
90            filter.word_list(),
91            &["hello", "world", "this", "is", "a", "test"]
92        );
93    }
94}