1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | // rustdoc-stripper-ignore-next |
4 | //! This module is inefficient and should not be used by Rust programs except for |
5 | //! compatibility with GLib.Regex based APIs. |
6 | |
7 | use crate::{ |
8 | ffi, translate::*, GStr, GStringPtr, MatchInfo, PtrSlice, Regex, RegexCompileFlags, |
9 | RegexMatchFlags, |
10 | }; |
11 | use std::{mem, ptr}; |
12 | |
13 | impl Regex { |
14 | #[doc (alias = "g_regex_get_string_number" )] |
15 | #[doc (alias = "get_string_number" )] |
16 | pub fn string_number(&self, name: impl IntoGStr) -> i32 { |
17 | name.run_with_gstr(|name| unsafe { |
18 | ffi::g_regex_get_string_number(self.to_glib_none().0, name.to_glib_none().0) |
19 | }) |
20 | } |
21 | |
22 | #[doc (alias = "g_regex_escape_nul" )] |
23 | pub fn escape_nul(string: impl IntoGStr) -> crate::GString { |
24 | unsafe { |
25 | string.run_with_gstr(|string| { |
26 | from_glib_full(ffi::g_regex_escape_nul( |
27 | string.to_glib_none().0, |
28 | string.len() as _, |
29 | )) |
30 | }) |
31 | } |
32 | } |
33 | |
34 | #[doc (alias = "g_regex_escape_string" )] |
35 | pub fn escape_string(string: impl IntoGStr) -> crate::GString { |
36 | unsafe { |
37 | string.run_with_gstr(|string| { |
38 | from_glib_full(ffi::g_regex_escape_string( |
39 | string.to_glib_none().0, |
40 | string.len() as _, |
41 | )) |
42 | }) |
43 | } |
44 | } |
45 | |
46 | #[doc (alias = "g_regex_check_replacement" )] |
47 | pub fn check_replacement(replacement: impl IntoGStr) -> Result<bool, crate::Error> { |
48 | replacement.run_with_gstr(|replacement| unsafe { |
49 | let mut has_references = mem::MaybeUninit::uninit(); |
50 | let mut error = ptr::null_mut(); |
51 | let is_ok = ffi::g_regex_check_replacement( |
52 | replacement.to_glib_none().0, |
53 | has_references.as_mut_ptr(), |
54 | &mut error, |
55 | ); |
56 | debug_assert_eq!(is_ok == crate::ffi::GFALSE, !error.is_null()); |
57 | if error.is_null() { |
58 | Ok(from_glib(has_references.assume_init())) |
59 | } else { |
60 | Err(from_glib_full(error)) |
61 | } |
62 | }) |
63 | } |
64 | |
65 | #[doc (alias = "g_regex_match_simple" )] |
66 | pub fn match_simple( |
67 | pattern: impl IntoGStr, |
68 | string: impl IntoGStr, |
69 | compile_options: RegexCompileFlags, |
70 | match_options: RegexMatchFlags, |
71 | ) -> bool { |
72 | pattern.run_with_gstr(|pattern| { |
73 | string.run_with_gstr(|string| unsafe { |
74 | from_glib(ffi::g_regex_match_simple( |
75 | pattern.to_glib_none().0, |
76 | string.to_glib_none().0, |
77 | compile_options.into_glib(), |
78 | match_options.into_glib(), |
79 | )) |
80 | }) |
81 | }) |
82 | } |
83 | |
84 | #[doc (alias = "g_regex_replace" )] |
85 | pub fn replace( |
86 | &self, |
87 | string: impl IntoGStr, |
88 | start_position: i32, |
89 | replacement: impl IntoGStr, |
90 | match_options: RegexMatchFlags, |
91 | ) -> Result<crate::GString, crate::Error> { |
92 | unsafe { |
93 | string.run_with_gstr(|string| { |
94 | replacement.run_with_gstr(|replacement| { |
95 | let mut error = ptr::null_mut(); |
96 | let ret = ffi::g_regex_replace( |
97 | self.to_glib_none().0, |
98 | string.as_ptr() as *const _, |
99 | string.len() as _, |
100 | start_position, |
101 | replacement.to_glib_none().0, |
102 | match_options.into_glib(), |
103 | &mut error, |
104 | ); |
105 | if error.is_null() { |
106 | Ok(from_glib_full(ret)) |
107 | } else { |
108 | Err(from_glib_full(error)) |
109 | } |
110 | }) |
111 | }) |
112 | } |
113 | } |
114 | |
115 | #[doc (alias = "g_regex_match_all" )] |
116 | pub fn match_all<'input>( |
117 | &self, |
118 | string: &'input GStr, |
119 | match_options: RegexMatchFlags, |
120 | ) -> Option<MatchInfo<'input>> { |
121 | self.match_all_full(string, 0, match_options).ok() |
122 | } |
123 | |
124 | #[doc (alias = "g_regex_match_all_full" )] |
125 | pub fn match_all_full<'input>( |
126 | &self, |
127 | string: &'input GStr, |
128 | start_position: i32, |
129 | match_options: RegexMatchFlags, |
130 | ) -> Result<MatchInfo<'input>, crate::Error> { |
131 | unsafe { |
132 | let mut match_info = ptr::null_mut(); |
133 | let mut error = ptr::null_mut(); |
134 | let is_ok = ffi::g_regex_match_all_full( |
135 | self.to_glib_none().0, |
136 | string.to_glib_none().0, |
137 | string.len() as _, |
138 | start_position, |
139 | match_options.into_glib(), |
140 | &mut match_info, |
141 | &mut error, |
142 | ); |
143 | debug_assert_eq!(is_ok == crate::ffi::GFALSE, !error.is_null()); |
144 | if error.is_null() { |
145 | Ok(from_glib_full(match_info)) |
146 | } else { |
147 | Err(from_glib_full(error)) |
148 | } |
149 | } |
150 | } |
151 | |
152 | #[doc (alias = "g_regex_match" )] |
153 | pub fn match_<'input>( |
154 | &self, |
155 | string: &'input GStr, |
156 | match_options: RegexMatchFlags, |
157 | ) -> Option<MatchInfo<'input>> { |
158 | self.match_full(string, 0, match_options).ok() |
159 | } |
160 | |
161 | #[doc (alias = "g_regex_match_full" )] |
162 | pub fn match_full<'input>( |
163 | &self, |
164 | string: &'input GStr, |
165 | start_position: i32, |
166 | match_options: RegexMatchFlags, |
167 | ) -> Result<MatchInfo<'input>, crate::Error> { |
168 | unsafe { |
169 | let mut match_info = ptr::null_mut(); |
170 | let mut error = ptr::null_mut(); |
171 | let is_ok = ffi::g_regex_match_full( |
172 | self.to_glib_none().0, |
173 | string.to_glib_none().0, |
174 | string.len() as _, |
175 | start_position, |
176 | match_options.into_glib(), |
177 | &mut match_info, |
178 | &mut error, |
179 | ); |
180 | debug_assert_eq!(is_ok == crate::ffi::GFALSE, !error.is_null()); |
181 | if error.is_null() { |
182 | Ok(from_glib_full(match_info)) |
183 | } else { |
184 | Err(from_glib_full(error)) |
185 | } |
186 | } |
187 | } |
188 | |
189 | #[doc (alias = "g_regex_replace_literal" )] |
190 | pub fn replace_literal( |
191 | &self, |
192 | string: impl IntoGStr, |
193 | start_position: i32, |
194 | replacement: impl IntoGStr, |
195 | match_options: RegexMatchFlags, |
196 | ) -> Result<crate::GString, crate::Error> { |
197 | unsafe { |
198 | string.run_with_gstr(|string| { |
199 | replacement.run_with_gstr(|replacement| { |
200 | let mut error = ptr::null_mut(); |
201 | let ret = ffi::g_regex_replace_literal( |
202 | self.to_glib_none().0, |
203 | string.to_glib_none().0, |
204 | string.len() as _, |
205 | start_position, |
206 | replacement.to_glib_none().0, |
207 | match_options.into_glib(), |
208 | &mut error, |
209 | ); |
210 | if error.is_null() { |
211 | Ok(from_glib_full(ret)) |
212 | } else { |
213 | Err(from_glib_full(error)) |
214 | } |
215 | }) |
216 | }) |
217 | } |
218 | } |
219 | |
220 | #[doc (alias = "g_regex_split" )] |
221 | pub fn split( |
222 | &self, |
223 | string: impl IntoGStr, |
224 | match_options: RegexMatchFlags, |
225 | ) -> PtrSlice<GStringPtr> { |
226 | self.split_full(string, 0, match_options, 0) |
227 | .unwrap_or_default() |
228 | } |
229 | |
230 | #[doc (alias = "g_regex_split_full" )] |
231 | pub fn split_full( |
232 | &self, |
233 | string: impl IntoGStr, |
234 | start_position: i32, |
235 | match_options: RegexMatchFlags, |
236 | max_tokens: i32, |
237 | ) -> Result<PtrSlice<GStringPtr>, crate::Error> { |
238 | unsafe { |
239 | let mut error = ptr::null_mut(); |
240 | string.run_with_gstr(|string| { |
241 | let ret = ffi::g_regex_split_full( |
242 | self.to_glib_none().0, |
243 | string.to_glib_none().0, |
244 | string.len() as _, |
245 | start_position, |
246 | match_options.into_glib(), |
247 | max_tokens, |
248 | &mut error, |
249 | ); |
250 | if error.is_null() { |
251 | Ok(FromGlibPtrContainer::from_glib_full(ret)) |
252 | } else { |
253 | Err(from_glib_full(error)) |
254 | } |
255 | }) |
256 | } |
257 | } |
258 | |
259 | #[doc (alias = "g_regex_split_simple" )] |
260 | pub fn split_simple( |
261 | pattern: impl IntoGStr, |
262 | string: impl IntoGStr, |
263 | compile_options: RegexCompileFlags, |
264 | match_options: RegexMatchFlags, |
265 | ) -> PtrSlice<GStringPtr> { |
266 | pattern.run_with_gstr(|pattern| { |
267 | string.run_with_gstr(|string| unsafe { |
268 | FromGlibPtrContainer::from_glib_full(ffi::g_regex_split_simple( |
269 | pattern.to_glib_none().0, |
270 | string.to_glib_none().0, |
271 | compile_options.into_glib(), |
272 | match_options.into_glib(), |
273 | )) |
274 | }) |
275 | }) |
276 | } |
277 | } |
278 | |
279 | #[cfg (test)] |
280 | mod tests { |
281 | use super::*; |
282 | use crate::RegexCompileFlags; |
283 | |
284 | #[test ] |
285 | fn test_replace_literal() { |
286 | let regex = Regex::new( |
287 | "s[ai]mple" , |
288 | RegexCompileFlags::OPTIMIZE, |
289 | RegexMatchFlags::DEFAULT, |
290 | ) |
291 | .expect("Regex new" ) |
292 | .expect("Null regex" ); |
293 | |
294 | let quote = "This is a simple sample." ; |
295 | let result = regex |
296 | .replace_literal(quote, 0, "XXX" , RegexMatchFlags::DEFAULT) |
297 | .expect("regex replace" ); |
298 | |
299 | assert_eq!(result, "This is a XXX XXX." ); |
300 | } |
301 | |
302 | #[test ] |
303 | fn test_split() { |
304 | let regex = Regex::new( |
305 | "s[ai]mple" , |
306 | RegexCompileFlags::OPTIMIZE, |
307 | RegexMatchFlags::DEFAULT, |
308 | ) |
309 | .expect("Regex new" ) |
310 | .expect("Null regex" ); |
311 | |
312 | let quote = "This is a simple sample." ; |
313 | let result = regex.split(quote, RegexMatchFlags::DEFAULT); |
314 | |
315 | assert_eq!(result.len(), 3); |
316 | assert_eq!(result[0], "This is a " ); |
317 | assert_eq!(result[1], " " ); |
318 | assert_eq!(result[2], "." ); |
319 | } |
320 | } |
321 | |