1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT

use crate::{translate::*, Error, RegexCompileFlags, RegexMatchFlags};

crate::wrapper! {
    /// A `GRegex` is the "compiled" form of a regular expression pattern.
    ///
    /// `GRegex` implements regular expression pattern matching using syntax and
    /// semantics similar to Perl regular expression. See the
    /// [PCRE documentation](man:pcrepattern(3)) for the syntax definition.
    ///
    /// Some functions accept a @start_position argument, setting it differs
    /// from just passing over a shortened string and setting [`RegexMatchFlags::NOTBOL`][crate::RegexMatchFlags::NOTBOL]
    /// in the case of a pattern that begins with any kind of lookbehind assertion.
    /// For example, consider the pattern "\Biss\B" which finds occurrences of "iss"
    /// in the middle of words. ("\B" matches only if the current position in the
    /// subject is not a word boundary.) When applied to the string "Mississipi"
    /// from the fourth byte, namely "issipi", it does not match, because "\B" is
    /// always false at the start of the subject, which is deemed to be a word
    /// boundary. However, if the entire string is passed , but with
    /// @start_position set to 4, it finds the second occurrence of "iss" because
    /// it is able to look behind the starting point to discover that it is
    /// preceded by a letter.
    ///
    /// Note that, unless you set the [`RegexCompileFlags::RAW`][crate::RegexCompileFlags::RAW] flag, all the strings passed
    /// to these functions must be encoded in UTF-8. The lengths and the positions
    /// inside the strings are in bytes and not in characters, so, for instance,
    /// "\xc3\xa0" (i.e. "à") is two bytes long but it is treated as a
    /// single character. If you set [`RegexCompileFlags::RAW`][crate::RegexCompileFlags::RAW] the strings can be non-valid
    /// UTF-8 strings and a byte is treated as a character, so "\xc3\xa0" is two
    /// bytes and two characters long.
    ///
    /// When matching a pattern, "\n" matches only against a "\n" character in
    /// the string, and "\r" matches only a "\r" character. To match any newline
    /// sequence use "\R". This particular group matches either the two-character
    /// sequence CR + LF ("\r\n"), or one of the single characters LF (linefeed,
    /// U+000A, "\n"), VT vertical tab, U+000B, "\v"), FF (formfeed, U+000C, "\f"),
    /// CR (carriage return, U+000D, "\r"), NEL (next line, U+0085), LS (line
    /// separator, U+2028), or PS (paragraph separator, U+2029).
    ///
    /// The behaviour of the dot, circumflex, and dollar metacharacters are
    /// affected by newline characters, the default is to recognize any newline
    /// character (the same characters recognized by "\R"). This can be changed
    /// with `G_REGEX_NEWLINE_CR`, `G_REGEX_NEWLINE_LF` and `G_REGEX_NEWLINE_CRLF`
    /// compile options, and with `G_REGEX_MATCH_NEWLINE_ANY`,
    /// `G_REGEX_MATCH_NEWLINE_CR`, `G_REGEX_MATCH_NEWLINE_LF` and
    /// `G_REGEX_MATCH_NEWLINE_CRLF` match options. These settings are also
    /// relevant when compiling a pattern if `G_REGEX_EXTENDED` is set, and an
    /// unescaped "#" outside a character class is encountered. This indicates
    /// a comment that lasts until after the next newline.
    ///
    /// Creating and manipulating the same `GRegex` structure from different
    /// threads is not a problem as `GRegex` does not modify its internal
    /// state between creation and destruction, on the other hand `GMatchInfo`
    /// is not threadsafe.
    ///
    /// The regular expressions low-level functionalities are obtained through
    /// the excellent [PCRE](http://www.pcre.org/) library written by Philip Hazel.
    #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
    pub struct Regex(Shared<ffi::GRegex>);

    match fn {
        ref => |ptr| ffi::g_regex_ref(ptr),
        unref => |ptr| ffi::g_regex_unref(ptr),
        type_ => || ffi::g_regex_get_type(),
    }
}

impl Regex {
    /// Compiles the regular expression to an internal form, and does
    /// the initial setup of the #GRegex structure.
    /// ## `pattern`
    /// the regular expression
    /// ## `compile_options`
    /// compile options for the regular expression, or 0
    /// ## `match_options`
    /// match options for the regular expression, or 0
    ///
    /// # Returns
    ///
    /// a #GRegex structure or [`None`] if an error occurred. Call
    ///   g_regex_unref() when you are done with it
    #[doc(alias = "g_regex_new")]
    pub fn new(
        pattern: &str,
        compile_options: RegexCompileFlags,
        match_options: RegexMatchFlags,
    ) -> Result<Option<Regex>, crate::Error> {
        unsafe {
            let mut error = std::ptr::null_mut();
            let ret = ffi::g_regex_new(
                pattern.to_glib_none().0,
                compile_options.into_glib(),
                match_options.into_glib(),
                &mut error,
            );
            if error.is_null() {
                Ok(from_glib_full(ret))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    /// Returns the number of capturing subpatterns in the pattern.
    ///
    /// # Returns
    ///
    /// the number of capturing subpatterns
    #[doc(alias = "g_regex_get_capture_count")]
    #[doc(alias = "get_capture_count")]
    pub fn capture_count(&self) -> i32 {
        unsafe { ffi::g_regex_get_capture_count(self.to_glib_none().0) }
    }

    /// Returns the compile options that @self was created with.
    ///
    /// Depending on the version of PCRE that is used, this may or may not
    /// include flags set by option expressions such as `(?i)` found at the
    /// top-level within the compiled pattern.
    ///
    /// # Returns
    ///
    /// flags from #GRegexCompileFlags
    #[doc(alias = "g_regex_get_compile_flags")]
    #[doc(alias = "get_compile_flags")]
    pub fn compile_flags(&self) -> RegexCompileFlags {
        unsafe { from_glib(ffi::g_regex_get_compile_flags(self.to_glib_none().0)) }
    }

    /// Checks whether the pattern contains explicit CR or LF references.
    ///
    /// # Returns
    ///
    /// [`true`] if the pattern contains explicit CR or LF references
    #[doc(alias = "g_regex_get_has_cr_or_lf")]
    #[doc(alias = "get_has_cr_or_lf")]
    pub fn has_cr_or_lf(&self) -> bool {
        unsafe { from_glib(ffi::g_regex_get_has_cr_or_lf(self.to_glib_none().0)) }
    }

    /// Returns the match options that @self was created with.
    ///
    /// # Returns
    ///
    /// flags from #GRegexMatchFlags
    #[doc(alias = "g_regex_get_match_flags")]
    #[doc(alias = "get_match_flags")]
    pub fn match_flags(&self) -> RegexMatchFlags {
        unsafe { from_glib(ffi::g_regex_get_match_flags(self.to_glib_none().0)) }
    }

    /// Returns the number of the highest back reference
    /// in the pattern, or 0 if the pattern does not contain
    /// back references.
    ///
    /// # Returns
    ///
    /// the number of the highest back reference
    #[doc(alias = "g_regex_get_max_backref")]
    #[doc(alias = "get_max_backref")]
    pub fn max_backref(&self) -> i32 {
        unsafe { ffi::g_regex_get_max_backref(self.to_glib_none().0) }
    }

    /// Gets the number of characters in the longest lookbehind assertion in the
    /// pattern. This information is useful when doing multi-segment matching using
    /// the partial matching facilities.
    ///
    /// # Returns
    ///
    /// the number of characters in the longest lookbehind assertion.
    #[doc(alias = "g_regex_get_max_lookbehind")]
    #[doc(alias = "get_max_lookbehind")]
    pub fn max_lookbehind(&self) -> i32 {
        unsafe { ffi::g_regex_get_max_lookbehind(self.to_glib_none().0) }
    }

    /// Gets the pattern string associated with @self, i.e. a copy of
    /// the string passed to g_regex_new().
    ///
    /// # Returns
    ///
    /// the pattern of @self
    #[doc(alias = "g_regex_get_pattern")]
    #[doc(alias = "get_pattern")]
    pub fn pattern(&self) -> crate::GString {
        unsafe { from_glib_none(ffi::g_regex_get_pattern(self.to_glib_none().0)) }
    }

    //#[doc(alias = "g_regex_replace_eval")]
    //pub fn replace_eval(&self, string: &[&str], start_position: i32, match_options: RegexMatchFlags, eval: /*Unimplemented*/FnMut(&MatchInfo, /*Ignored*/String) -> bool, user_data: /*Unimplemented*/Option<Basic: Pointer>) -> Result<crate::GString, crate::Error> {
    //    unsafe { TODO: call ffi:g_regex_replace_eval() }
    //}
}