easy_regex/
literal.rs

1//! Creates expressions to match literal characters.
2//! 
3//! The most basic way of writing regex using this crate is by calling the [`literal`](../struct.EasyRegex.html#method.literal) method.
4//! As the name implies, it's for creating regular expressions that should match characters literally.
5//! It cannot be used as the very first method but it is the backbone of other important methods (e.g. [`group`](../struct.EasyRegex.html#method.group) method).
6//! It takes an expression and a set of settings (special characters, flags etc.) and outputs an ```EasyRegex``` instance.
7
8use crate::{settings::*, EasyRegex};
9
10impl EasyRegex {
11    /// Creates a literal regular expression.
12    /// 
13    /// This method takes an expression (a segment of entire pattern) followed
14    /// by a set of settings (```Settings``` struct) that will be concatenated/inserted to the expression itself,
15    /// outputing the previous pattern followed by this prepared regular expression.
16    ///
17    /// # Examples
18    ///
19    /// ```
20    /// use easy_regex::{EasyRegex, settings::base::DEFAULT};
21    /// 
22    /// let result = EasyRegex::new_section().literal("some expression", &DEFAULT);
23    /// assert_eq!("some expression", result.get_regex().unwrap().as_str());
24    /// ```
25    pub fn literal(self, expression: &str, settings: &Settings) -> EasyRegex {
26        let mut final_result = expression.to_string();
27
28        if let Some(flag) = settings.flags {
29            let mut stringified_flag = flag.as_str().to_string();
30            stringified_flag = format!("({})", stringified_flag);
31            stringified_flag.push_str(expression);
32            final_result = stringified_flag;
33        }
34        if settings.with_left_boundary {
35            let mut boundary = String::from("\\b");
36            boundary.push_str(&final_result);
37            final_result = boundary;
38        }
39        if settings.with_left_non_boundary {
40            let mut boundary = String::from("\\B");
41            boundary.push_str(&final_result);
42            final_result = boundary;
43        }
44        if settings.range.is_some()
45            && (settings.range.unwrap().0.is_some() || settings.range.unwrap().1.is_some())
46        {
47            let numbers = settings.range.unwrap();
48
49            final_result.push_str("{");
50
51            if let Some(start_range) = numbers.0 {
52                final_result.push_str(&start_range.to_string());
53            }
54
55            final_result.push_str(",");
56
57            if let Some(end_range) = numbers.1 {
58                final_result.push_str(&end_range.to_string());
59            }
60
61            final_result.push_str("}");
62        }
63        if let Some(number) = settings.exactly {
64            final_result.push_str("{");
65            final_result.push_str(&number.to_string());
66            final_result.push_str("}");
67        }
68        if settings.is_nil_or_more {
69            final_result.push_str("*");
70        }
71        if settings.is_one_or_more {
72            final_result.push_str("+");
73        }
74        if settings.is_optional {
75            final_result.push_str("?");
76        }
77        if settings.is_optional_ungreedy {
78            final_result.push_str("??");
79        }
80        if settings.with_right_boundary {
81            final_result.push_str("\\b");
82        }
83        if settings.with_right_non_boundary {
84            final_result.push_str("\\B");
85        }
86
87        final_result = format!("{}{}", &self.0, final_result);
88        EasyRegex(final_result)
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use crate::settings::base::*;
95
96    use self::EasyRegex;
97    use super::*;
98
99    #[test]
100    fn literal_exp_works() {
101        let initial_exp = EasyRegex::new("initial_");
102        let result = initial_exp.literal("abcd", &DEFAULT);
103        assert_eq!(result.0, "initial_abcd");
104    }
105
106    #[test]
107    fn literal_exp_optional_works() {
108        let initial_exp = EasyRegex::new("initial_");
109        let result = initial_exp.literal("abcd", &OPTIONAL);
110        assert_eq!(result.0, "initial_abcd?");
111    }
112
113    #[test]
114    fn literal_exp_range_works() {
115        let initial_exp = EasyRegex::new("initial_");
116        let result = initial_exp.literal(
117            "abcd",
118            &Settings {
119                is_optional: true,
120                range: Some((None, Some(2))),
121                ..Default::default()
122            },
123        );
124        assert_eq!(result.0, "initial_abcd{,2}?");
125    }
126
127    #[test]
128    fn literal_exp_boundary_works() {
129        let initial_exp = EasyRegex::new("initial_");
130        let result = initial_exp.literal(
131            "abcd",
132            &Settings {
133                with_left_boundary: true,
134                with_right_boundary: true,
135                ..Default::default()
136            },
137        );
138        assert_eq!(result.0, "initial_\\babcd\\b");
139    }
140
141    #[test]
142    fn literal_exp_mixed_works() {
143        let initial_exp = EasyRegex::new("initial_");
144        let result = initial_exp.literal(
145            "ab\\scd",
146            &Settings {
147                is_optional: true,
148                with_left_boundary: true,
149                with_right_boundary: true,
150                range: Some((None, Some(5))),
151                ..Default::default()
152            },
153        );
154        assert_eq!(result.0, "initial_\\bab\\scd{,5}?\\b");
155    }
156
157    #[test]
158    fn literal_exp_works_with_range_and_start_and_plus() {
159        let initial_exp = EasyRegex::new("initial_");
160        let result = initial_exp.literal(
161            "ab\\scd",
162            &Settings {
163                is_nil_or_more: true,
164                range: Some((Some(2), None)),
165                ..Default::default()
166            },
167        );
168
169        assert_eq!("initial_ab\\scd{2,}*", result.get_regex().unwrap().as_str());
170    }
171
172    #[test]
173    fn literal_exp_works_with_star_and_plus() {
174        let initial_exp = EasyRegex::new("initial_");
175        let result = initial_exp.literal(
176            "ab\\scd",
177            &Settings {
178                is_nil_or_more: true,
179                is_one_or_more: true,
180                ..Default::default()
181            },
182        );
183
184        assert_eq!("initial_ab\\scd*+", result.get_regex().unwrap().as_str());
185    }
186
187    #[test]
188    fn literal_exp_works_with_range_and_exact() {
189        let initial_exp = EasyRegex::new("initial_");
190        let result = initial_exp.literal(
191            "ab\\scd",
192            &Settings {
193                range: Some((Some(2), Some(10))),
194                exactly: Some(8),
195                ..Default::default()
196            },
197        );
198
199        assert_eq!(
200            "initial_ab\\scd{2,10}{8}",
201            result.get_regex().unwrap().as_str()
202        );
203    }
204}