Skip to main content

ferray_strings/
strip.rs

1// ferray-strings: Stripping operations (REQ-7)
2//
3// Implements strip, lstrip, rstrip — elementwise on StringArray.
4
5use ferray_core::dimension::Dimension;
6use ferray_core::error::FerrayResult;
7
8use crate::string_array::StringArray;
9
10/// Strip leading and trailing characters from each string element.
11///
12/// If `chars` is `None`, strips whitespace. Otherwise strips any character
13/// present in the `chars` string.
14///
15/// # Errors
16/// Returns an error if the internal array construction fails.
17pub fn strip<D: Dimension>(
18    a: &StringArray<D>,
19    chars: Option<&str>,
20) -> FerrayResult<StringArray<D>> {
21    match chars {
22        None => a.map(|s| s.trim().to_string()),
23        Some(ch) => {
24            let char_set: Vec<char> = ch.chars().collect();
25            a.map(|s| s.trim_matches(|c: char| char_set.contains(&c)).to_string())
26        }
27    }
28}
29
30/// Strip leading characters from each string element.
31///
32/// If `chars` is `None`, strips leading whitespace. Otherwise strips any
33/// character present in the `chars` string from the left.
34///
35/// # Errors
36/// Returns an error if the internal array construction fails.
37pub fn lstrip<D: Dimension>(
38    a: &StringArray<D>,
39    chars: Option<&str>,
40) -> FerrayResult<StringArray<D>> {
41    match chars {
42        None => a.map(|s| s.trim_start().to_string()),
43        Some(ch) => {
44            let char_set: Vec<char> = ch.chars().collect();
45            a.map(|s| {
46                s.trim_start_matches(|c: char| char_set.contains(&c))
47                    .to_string()
48            })
49        }
50    }
51}
52
53/// Strip trailing characters from each string element.
54///
55/// If `chars` is `None`, strips trailing whitespace. Otherwise strips any
56/// character present in the `chars` string from the right.
57///
58/// # Errors
59/// Returns an error if the internal array construction fails.
60pub fn rstrip<D: Dimension>(
61    a: &StringArray<D>,
62    chars: Option<&str>,
63) -> FerrayResult<StringArray<D>> {
64    match chars {
65        None => a.map(|s| s.trim_end().to_string()),
66        Some(ch) => {
67            let char_set: Vec<char> = ch.chars().collect();
68            a.map(|s| {
69                s.trim_end_matches(|c: char| char_set.contains(&c))
70                    .to_string()
71            })
72        }
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79    use crate::string_array::array;
80
81    #[test]
82    fn test_strip_whitespace() {
83        let a = array(&["  hello  ", "\tworld\n"]).unwrap();
84        let b = strip(&a, None).unwrap();
85        assert_eq!(b.as_slice(), &["hello", "world"]);
86    }
87
88    #[test]
89    fn test_strip_chars() {
90        let a = array(&["xxhelloxx", "xyworldyx"]).unwrap();
91        let b = strip(&a, Some("xy")).unwrap();
92        assert_eq!(b.as_slice(), &["hello", "world"]);
93    }
94
95    #[test]
96    fn test_lstrip_whitespace() {
97        let a = array(&["  hello  ", "\tworld\n"]).unwrap();
98        let b = lstrip(&a, None).unwrap();
99        assert_eq!(b.as_slice(), &["hello  ", "world\n"]);
100    }
101
102    #[test]
103    fn test_lstrip_chars() {
104        let a = array(&["xxhello", "xyhello"]).unwrap();
105        let b = lstrip(&a, Some("xy")).unwrap();
106        assert_eq!(b.as_slice(), &["hello", "hello"]);
107    }
108
109    #[test]
110    fn test_rstrip_whitespace() {
111        let a = array(&["  hello  ", "\tworld\n"]).unwrap();
112        let b = rstrip(&a, None).unwrap();
113        assert_eq!(b.as_slice(), &["  hello", "\tworld"]);
114    }
115
116    #[test]
117    fn test_rstrip_chars() {
118        let a = array(&["helloxx", "worldyx"]).unwrap();
119        let b = rstrip(&a, Some("xy")).unwrap();
120        assert_eq!(b.as_slice(), &["hello", "world"]);
121    }
122
123    #[test]
124    fn test_strip_empty_string() {
125        let a = array(&["", "   "]).unwrap();
126        let b = strip(&a, None).unwrap();
127        assert_eq!(b.as_slice(), &["", ""]);
128    }
129}