1 #![allow(clippy::transmute_ptr_to_ptr)]
2 #![allow(clippy::transmute_ptr_to_ref)]
3 
4 use super::{MetaCharType, RegexOptions, SyntaxBehavior, SyntaxOperator};
5 use onig_sys;
6 use std::mem::transmute;
7 
8 /// Meta Character State
9 ///
10 /// Defines if a given meta character is enabled or not within a given
11 /// syntax. If the character is enabled it also contains the rust
12 /// `char` that it is set to.
13 #[derive(Copy, Clone)]
14 pub enum MetaChar {
15     /// The meta character is set to the chosen `char`
16     Character(char),
17     /// The meta character is not enabled
18     Ineffective,
19 }
20 
21 /// Onig Syntax Wrapper
22 ///
23 /// Each syntax dfines a flavour of regex syntax. This type allows
24 /// interaction with the built-in syntaxes through the static accessor
25 /// functions (`Syntax::emacs()`, `Syntax::default()` etc.) and the
26 /// creation of custom syntaxes.
27 ///
28 /// For a demonstration of creating a custom syntax see
29 /// `examples/syntax.rs` in the main onig crate.
30 #[derive(Debug, Clone, Copy)]
31 #[repr(transparent)]
32 pub struct Syntax {
33     raw: onig_sys::OnigSyntaxType,
34 }
35 
36 impl Syntax {
37     /// Python syntax
python() -> &'static Syntax38     pub fn python() -> &'static Syntax {
39         unsafe { transmute(&onig_sys::OnigSyntaxPython) }
40     }
41     /// Plain text syntax
asis() -> &'static Syntax42     pub fn asis() -> &'static Syntax {
43         unsafe { transmute(&onig_sys::OnigSyntaxASIS) }
44     }
45 
46     /// POSIX Basic RE syntax
posix_basic() -> &'static Syntax47     pub fn posix_basic() -> &'static Syntax {
48         unsafe { transmute(&onig_sys::OnigSyntaxPosixBasic) }
49     }
50 
51     /// POSIX Extended RE syntax
posix_extended() -> &'static Syntax52     pub fn posix_extended() -> &'static Syntax {
53         unsafe { transmute(&onig_sys::OnigSyntaxPosixExtended) }
54     }
55 
56     /// Emacs syntax
emacs() -> &'static Syntax57     pub fn emacs() -> &'static Syntax {
58         unsafe { transmute(&onig_sys::OnigSyntaxEmacs) }
59     }
60 
61     /// Grep syntax
grep() -> &'static Syntax62     pub fn grep() -> &'static Syntax {
63         unsafe { transmute(&onig_sys::OnigSyntaxGrep) }
64     }
65 
66     /// GNU regex syntax
gnu_regex() -> &'static Syntax67     pub fn gnu_regex() -> &'static Syntax {
68         unsafe { transmute(&onig_sys::OnigSyntaxGnuRegex) }
69     }
70 
71     /// Java (Sun java.util.regex) syntax
java() -> &'static Syntax72     pub fn java() -> &'static Syntax {
73         unsafe { transmute(&onig_sys::OnigSyntaxJava) }
74     }
75 
76     /// Perl syntax
perl() -> &'static Syntax77     pub fn perl() -> &'static Syntax {
78         unsafe { transmute(&onig_sys::OnigSyntaxPerl) }
79     }
80 
81     /// Perl + named group syntax
perl_ng() -> &'static Syntax82     pub fn perl_ng() -> &'static Syntax {
83         unsafe { transmute(&onig_sys::OnigSyntaxPerl_NG) }
84     }
85 
86     /// Ruby syntax
ruby() -> &'static Syntax87     pub fn ruby() -> &'static Syntax {
88         unsafe { transmute(&onig_sys::OnigSyntaxRuby) }
89     }
90 
91     /// Oniguruma Syntax
oniguruma() -> &'static Syntax92     pub fn oniguruma() -> &'static Syntax {
93         unsafe { transmute(&onig_sys::OnigSyntaxOniguruma) }
94     }
95 
96     /// Default syntax (Ruby syntax)
default() -> &'static Syntax97     pub fn default() -> &'static Syntax {
98         unsafe { transmute(onig_sys::OnigDefaultSyntax) }
99     }
100 
101     /// Retrieve the operators for this syntax
operators(&self) -> SyntaxOperator102     pub fn operators(&self) -> SyntaxOperator {
103         unsafe {
104             let op = onig_sys::onig_get_syntax_op(self.raw_mut());
105             let op2 = onig_sys::onig_get_syntax_op2(self.raw_mut());
106             SyntaxOperator::from_bits_truncate(u64::from(op) + (u64::from(op2) << 32))
107         }
108     }
109 
110     /// Replace the operators for this syntax
set_operators(&mut self, operators: SyntaxOperator)111     pub fn set_operators(&mut self, operators: SyntaxOperator) {
112         let op = operators.bits() as onig_sys::OnigSyntaxOp;
113         let op2 = (operators.bits() >> 32) as onig_sys::OnigSyntaxOp2;
114         unsafe {
115             onig_sys::onig_set_syntax_op(&mut self.raw, op);
116             onig_sys::onig_set_syntax_op2(&mut self.raw, op2)
117         }
118     }
119 
120     /// Enable Operators for this Syntax
121     ///
122     /// Updates the operators for this syntax to enable the chosen
123     /// ones.
enable_operators(&mut self, operators: SyntaxOperator)124     pub fn enable_operators(&mut self, operators: SyntaxOperator) {
125         let operators = self.operators() | operators;
126         self.set_operators(operators)
127     }
128 
129     /// Disable Operators for this Syntax
130     ///
131     /// Updates the operators for this syntax to remove the specified
132     /// operators.
disable_operators(&mut self, operators: SyntaxOperator)133     pub fn disable_operators(&mut self, operators: SyntaxOperator) {
134         let operators = self.operators() & !operators;
135         self.set_operators(operators)
136     }
137 
138     /// Retrieves the syntax behaviours
behavior(&self) -> SyntaxBehavior139     pub fn behavior(&self) -> SyntaxBehavior {
140         SyntaxBehavior::from_bits_truncate(unsafe {
141             onig_sys::onig_get_syntax_behavior(self.raw_mut())
142         })
143     }
144 
145     /// Overwrite the syntax behaviour for this syntax.
set_behavior(&mut self, behavior: SyntaxBehavior)146     pub fn set_behavior(&mut self, behavior: SyntaxBehavior) {
147         let behavior = behavior.bits() as onig_sys::OnigSyntaxBehavior;
148         unsafe {
149             onig_sys::onig_set_syntax_behavior(&mut self.raw, behavior);
150         }
151     }
152 
153     /// Enable a given behaviour for this syntax
enable_behavior(&mut self, behavior: SyntaxBehavior)154     pub fn enable_behavior(&mut self, behavior: SyntaxBehavior) {
155         let behavior = self.behavior() | behavior;
156         self.set_behavior(behavior)
157     }
158 
159     /// Disable a given behaviour for this syntax
disable_behavior(&mut self, behavior: SyntaxBehavior)160     pub fn disable_behavior(&mut self, behavior: SyntaxBehavior) {
161         let behavior = self.behavior() & !behavior;
162         self.set_behavior(behavior)
163     }
164 
165     /// Retireve the syntax options for this syntax
options(&self) -> RegexOptions166     pub fn options(&self) -> RegexOptions {
167         RegexOptions::from_bits_truncate(unsafe {
168             onig_sys::onig_get_syntax_options(self.raw_mut())
169         })
170     }
171 
172     /// Replace the syntax options for this syntax
set_options(&mut self, options: RegexOptions)173     pub fn set_options(&mut self, options: RegexOptions) {
174         let options = options.bits() as onig_sys::OnigOptionType;
175         unsafe {
176             onig_sys::onig_set_syntax_options(&mut self.raw, options);
177         }
178     }
179 
180     /// Set a given meta character's state
181     ///
182     /// Arguments:
183     ///  - `what`: The meta character to update
184     ///  - `meta`: The value to set the meta character to
set_meta_char(&mut self, what: MetaCharType, meta: MetaChar)185     pub fn set_meta_char(&mut self, what: MetaCharType, meta: MetaChar) {
186         let what = what.bits();
187         let code = match meta {
188             MetaChar::Ineffective => onig_sys::ONIG_INEFFECTIVE_META_CHAR,
189             MetaChar::Character(char) => char as u32,
190         };
191         unsafe {
192             onig_sys::onig_set_meta_char(&mut self.raw, what, code);
193         }
194     }
195 
raw_mut(&self) -> *mut onig_sys::OnigSyntaxType196     fn raw_mut(&self) -> *mut onig_sys::OnigSyntaxType {
197         &self.raw as *const onig_sys::OnigSyntaxType as *mut onig_sys::OnigSyntaxType
198     }
199 }
200