1use crate::{
8 ffi, translate::*, GStr, GStringPtr, MatchInfo, PtrSlice, Regex, RegexCompileFlags,
9 RegexMatchFlags,
10};
11use std::{mem, ptr};
12
13impl 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)]
280mod 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}