simple_string_patterns/
segments.rs1use crate::{simple_match::*, utils::extract_string_element_by_index};
2
3pub trait ToSegments {
8
9 fn to_segments(&self, separator: &str) -> Vec<String>;
12
13 fn to_parts(&self, separator: &str) -> Vec<String>;
15
16 fn to_head(&self, separator: &str) -> String;
18
19 fn to_first(&self, separator: &str) -> String;
21
22 fn to_remainder_end(&self, separator: &str) -> String;
24
25 fn to_last(&self, separator: &str) -> String;
27
28 fn to_remainder_start(&self, separator: &str) -> String;
30
31 fn to_end(&self, separator: &str) -> String;
33
34 fn to_segment(&self, separator: &str, index: i32) -> Option<String> {
39 let parts = self.to_segments(separator);
40 extract_string_element_by_index(parts, index)
41 }
42
43 fn to_part(&self, separator: &str, index: i32) -> Option<String> {
47 let parts = self.to_parts(separator);
48 extract_string_element_by_index(parts, index)
49 }
50
51 fn to_inner_segment(&self, groups: &[(&str, i32)]) -> Option<String>;
53
54 fn to_tail(&self, separator: &str) -> String;
56
57 fn to_head_tail(&self, separator: &str) -> (String, String);
59
60 fn to_start_end(&self, separator: &str) -> (String, String);
62
63}
64
65impl ToSegments for str {
67
68 fn to_parts(&self, separator: &str) -> Vec<String> {
71 let splitter = self.split(separator);
72 splitter.into_iter().map(|s| s.to_string()).collect::<Vec<String>>()
73 }
74
75 fn to_segments(&self, separator: &str) -> Vec<String> {
78 let splitter = self.split(separator);
79 splitter.into_iter().map(|s| s.to_string()).filter(|s| s.len() > 0).collect::<Vec<String>>()
80 }
81
82 fn to_head(&self, separator: &str) -> String {
84 if let Some((head, _tail)) = self.split_once(separator) {
85 head.to_string()
86 } else {
87 self.to_owned()
88 }
89 }
90
91 fn to_last(&self, separator: &str) -> String {
93 let separator_len = separator.len();
94 if self.ends_with(separator) && self.len() > separator_len {
95 let end_index = self.len() - separator_len;
96 self[0..end_index].to_string().to_end(separator)
97 } else {
98 self.to_end(separator)
99 }
100 }
101
102 fn to_end(&self, separator: &str) -> String {
104 let parts = self.to_parts(separator);
105 if let Some(end) = parts.last() {
106 end.to_owned()
107 } else {
108 self.to_owned()
109 }
110 }
111
112 fn to_tail(&self, separator: &str) -> String {
115 let parts = self.to_parts(separator);
116 let num_parts = parts.len();
117 if num_parts > 0 {
118 parts[1..num_parts].join(separator)
119 } else {
120 self.to_owned()
121 }
122 }
123
124 fn to_first(&self, separator: &str) -> String {
126 let separator_len = separator.len();
127 if self.starts_with(separator) && self.len() > separator_len {
128 self[separator_len..self.len()].to_string().to_head(separator)
129 } else {
130 self.to_head(separator)
131 }
132 }
133
134 fn to_remainder_end(&self, separator: &str) -> String {
136 let separator_len = separator.len();
137 if self.starts_with(separator) && self.len() > separator_len {
138 self[separator_len..].to_string().to_tail(separator)
139 } else {
140 self.to_tail(separator)
141 }
142 }
143
144 fn to_remainder_start(&self, separator: &str) -> String {
146 let separator_len = separator.len();
147 if self.ends_with(separator) && self.len() > separator_len {
148 let end_index = self.len() - separator_len;
149 self[0..end_index].to_string().to_tail(separator)
150 } else {
151 self.to_tail(separator)
152 }
153 }
154
155 fn to_inner_segment(&self, groups: &[(&str, i32)]) -> Option<String> {
159 if groups.len() > 0 {
160 let mut matched: Option<String> = None;
161 let mut current_string = self.to_string();
162 for group in groups {
163 if current_string.len() > 0 {
164 let (separator, index) = group;
165 matched = current_string.to_segment(*separator, *index);
166 current_string = matched.clone().unwrap_or("".to_string());
167 }
168 }
169 matched
170 } else {
171 None
172 }
173 }
174
175 fn to_head_tail(&self, separator: &str) -> (String, String) {
179 if let Some((head, tail)) = self.split_once(separator) {
180 (head.to_string(), tail.to_string())
181 } else {
182 ("".to_owned(), self.to_owned())
183 }
184 }
185
186 fn to_start_end(&self, separator: &str) -> (String, String) {
190 if let Some((start, end)) = self.rsplit_once(separator) {
191 (start.to_string(), end.to_string())
192 } else {
193 (self.to_owned(), "".to_string())
194 }
195 }
196
197}
198
199
200pub trait ToSegmentsFromChars {
202
203 fn split_on_any_char(&self, separators: &[char]) -> Vec<String>;
205
206 fn to_head_tail_on_any_char(&self, separators: &[char]) -> (String, String);
210
211 fn to_start_end_on_any_char(&self, separators: &[char]) -> (String, String);
215}
216
217impl ToSegmentsFromChars for str {
218
219 fn split_on_any_char(&self, separators: &[char]) -> Vec<String> {
221 let mut parts: Vec<String> = Vec::new();
222 let mut has_match = false;
223 let mut indices: Vec<usize> = Vec::new();
224 for separator in separators {
225 for matched_index in self.find_char_indices(*separator) {
226 indices.push(matched_index);
227 }
228 }
229 indices.sort_by(|a, b| a.cmp(b));
230 let mut prev_start = 0;
231 for index in indices {
232 let segment = self[prev_start..index].to_string();
233 parts.push(segment);
234 has_match = true;
235 prev_start = index + 1;
236 }
237 if has_match {
238 parts.push(self[prev_start..].to_string());
239 parts
240 } else {
241 vec![self.to_owned()]
242 }
243 }
244
245 fn to_head_tail_on_any_char(&self, separators: &[char]) -> (String, String) {
247 for ch in separators {
248 if self.contains(*ch) {
249 if let Some ((first, second)) = self.split_once(*ch) {
250 return (first.to_string(), second.to_string());
251 }
252 }
253 }
254 ("".to_owned(), self.to_string())
255 }
256
257 fn to_start_end_on_any_char(&self, separators: &[char]) -> (String, String) {
259 for ch in separators {
260 if self.contains(*ch) {
261 if let Some ((first, second)) = self.rsplit_once(*ch) {
262 return (first.to_string(), second.to_string());
263 }
264 }
265 }
266 (self.to_string(), "".to_owned())
267 }
268
269}