string_patterns/
pattern_split.rs

1use regex::Error;
2use crate::utils::build_regex;
3
4/// Provides methods to split a &str/string on a regular expression
5pub trait PatternSplit {
6  /// Splits a string on a regular expression with boolean case_insensitive flag. 
7  /// Returns result with vector of the parts between matches.
8  fn pattern_split_result(&self, pattern: &str, case_sensitive: bool) -> Result<Vec<String>, Error>;
9
10  /// Splits a string on a regular expression with boolean case_insensitive flag. 
11  /// Returns result with a tuple with head and tail or an error.
12  fn pattern_split_pair_result(&self, pattern: &str, case_sensitive: bool) -> Result<(String, String), Error>;
13
14  /// Splits a string on a regular expression with boolean case_insensitive flag. 
15  /// Returns  a vector of strings, empty if the regular expression fails.
16  fn pattern_split(&self, pattern: &str, case_sensitive: bool) -> Vec<String> {
17    match self.pattern_split_result(pattern, case_sensitive) {
18      Ok(parts) => parts,
19      Err(_error) => vec![],
20    }
21  }
22
23  /// Splits a string on a regular expression in case-isensitive mode. 
24  /// Returns  a vector of strings, empty if the regular expression fails.
25  fn pattern_split_ci(&self, pattern: &str) -> Vec<String> {
26    self.pattern_split(pattern, true)
27  }
28
29  /// Splits a string on a regular expression in case-sensitive mode. 
30  /// Returns  a vector of strings, empty if the regular expression fails.
31  fn pattern_split_cs(&self, pattern: &str) -> Vec<String> {
32    self.pattern_split(pattern, false)
33  }
34
35  /// Splits a string on a regular expression with boolean case_insensitive flag. 
36  /// Returns a tuple with head and tail. The tail will be en empty string if not matched
37  fn pattern_split_pair(&self, pattern: &str, case_sensitive: bool) -> (String, String) {
38    match self.pattern_split_pair_result(pattern, case_sensitive) {
39      Ok(parts) => parts,
40      Err(_error) => ("".to_owned(), "".to_owned()),
41    }
42  }
43
44  /// Split a string on a regular expression in case-isensitive mode. 
45  /// Returns a tuple with head and tail. The tail will be en empty string if not matched
46  fn pattern_split_pair_ci(&self, pattern: &str) -> (String, String) {
47    self.pattern_split_pair(pattern, true)
48  }
49
50  /// Split a string on a regular expression in case-sensitive mode. 
51  /// Returns a tuple with head and tail. The tail will be en empty string if not matched
52  fn pattern_split_pair_cs(&self, pattern: &str) -> (String, String) {
53    self.pattern_split_pair(pattern, false)
54  }
55
56}
57
58/// Implemented for &str and available to String too
59impl PatternSplit for str {
60
61  /// Split a string on a regular expression into a result with a vector of strings
62  fn pattern_split_result(&self, pattern: &str, case_sensitive: bool) -> Result<Vec<String>, Error> {
63    match build_regex(pattern, case_sensitive) {
64      Ok(regex) => Ok(regex.split(self).into_iter().map(|s| s.to_string()).collect::<Vec<String>>()),
65      Err(error) => Err(error),
66    }
67  }
68
69  /// Split a string on a regular expression into a result with a tuple of head / tail strings
70  fn pattern_split_pair_result(&self, pattern: &str, case_sensitive: bool) -> Result<(String, String), Error> {
71    match build_regex(pattern, case_sensitive) {
72      Ok(regex) => {
73        let parts = regex.splitn(self, 2).collect::<Vec<&str>>();
74        let head = parts.get(0).unwrap_or(&"").to_owned().to_string();
75        let tail = parts.get(1).unwrap_or(&"").to_owned().to_string();
76        Ok((head, tail))
77      },
78      Err(error) => Err(error),
79    }
80  }
81
82}