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     /// Plain text syntax
asis() -> &'static Syntax38     pub fn asis() -> &'static Syntax {
39         unsafe { transmute(&onig_sys::OnigSyntaxASIS) }
40     }
41 
42     /// POSIX Basic RE syntax
posix_basic() -> &'static Syntax43     pub fn posix_basic() -> &'static Syntax {
44         unsafe { transmute(&onig_sys::OnigSyntaxPosixBasic) }
45     }
46 
47     /// POSIX Extended RE syntax
posix_extended() -> &'static Syntax48     pub fn posix_extended() -> &'static Syntax {
49         unsafe { transmute(&onig_sys::OnigSyntaxPosixExtended) }
50     }
51 
52     /// Emacs syntax
emacs() -> &'static Syntax53     pub fn emacs() -> &'static Syntax {
54         unsafe { transmute(&onig_sys::OnigSyntaxEmacs) }
55     }
56 
57     /// Grep syntax
grep() -> &'static Syntax58     pub fn grep() -> &'static Syntax {
59         unsafe { transmute(&onig_sys::OnigSyntaxGrep) }
60     }
61 
62     /// GNU regex syntax
gnu_regex() -> &'static Syntax63     pub fn gnu_regex() -> &'static Syntax {
64         unsafe { transmute(&onig_sys::OnigSyntaxGnuRegex) }
65     }
66 
67     /// Java (Sun java.util.regex) syntax
java() -> &'static Syntax68     pub fn java() -> &'static Syntax {
69         unsafe { transmute(&onig_sys::OnigSyntaxJava) }
70     }
71 
72     /// Perl syntax
perl() -> &'static Syntax73     pub fn perl() -> &'static Syntax {
74         unsafe { transmute(&onig_sys::OnigSyntaxPerl) }
75     }
76 
77     /// Perl + named group syntax
perl_ng() -> &'static Syntax78     pub fn perl_ng() -> &'static Syntax {
79         unsafe { transmute(&onig_sys::OnigSyntaxPerl_NG) }
80     }
81 
82     /// Ruby syntax
ruby() -> &'static Syntax83     pub fn ruby() -> &'static Syntax {
84         unsafe { transmute(&onig_sys::OnigSyntaxRuby) }
85     }
86 
87     /// Oniguruma Syntax
oniguruma() -> &'static Syntax88     pub fn oniguruma() -> &'static Syntax {
89         unsafe { transmute(&onig_sys::OnigSyntaxOniguruma) }
90     }
91 
92     /// Default syntax (Ruby syntax)
default() -> &'static Syntax93     pub fn default() -> &'static Syntax {
94         unsafe { transmute(onig_sys::OnigDefaultSyntax) }
95     }
96 
97     /// Retrieve the operators for this syntax
operators(&self) -> SyntaxOperator98     pub fn operators(&self) -> SyntaxOperator {
99         unsafe {
100             let op = onig_sys::onig_get_syntax_op(self.raw_mut());
101             let op2 = onig_sys::onig_get_syntax_op2(self.raw_mut());
102             SyntaxOperator::from_bits_truncate(u64::from(op) + (u64::from(op2) << 32))
103         }
104     }
105 
106     /// Replace the operators for this syntax
set_operators(&mut self, operators: SyntaxOperator)107     pub fn set_operators(&mut self, operators: SyntaxOperator) {
108         let op = operators.bits() as onig_sys::OnigSyntaxOp;
109         let op2 = (operators.bits() >> 32) as onig_sys::OnigSyntaxOp2;
110         unsafe {
111             onig_sys::onig_set_syntax_op(&mut self.raw, op);
112             onig_sys::onig_set_syntax_op2(&mut self.raw, op2)
113         }
114     }
115 
116     /// Enable Operators for this Syntax
117     ///
118     /// Updates the operators for this syntax to enable the chosen
119     /// ones.
enable_operators(&mut self, operators: SyntaxOperator)120     pub fn enable_operators(&mut self, operators: SyntaxOperator) {
121         let operators = self.operators() | operators;
122         self.set_operators(operators)
123     }
124 
125     /// Disable Operators for this Syntax
126     ///
127     /// Updates the operators for this syntax to remove the specified
128     /// operators.
disable_operators(&mut self, operators: SyntaxOperator)129     pub fn disable_operators(&mut self, operators: SyntaxOperator) {
130         let operators = self.operators() & !operators;
131         self.set_operators(operators)
132     }
133 
134     /// Retrieves the syntax behaviours
behavior(&self) -> SyntaxBehavior135     pub fn behavior(&self) -> SyntaxBehavior {
136         SyntaxBehavior::from_bits_truncate(unsafe {
137             onig_sys::onig_get_syntax_behavior(self.raw_mut())
138         })
139     }
140 
141     /// Overwrite the syntax behaviour for this syntax.
set_behavior(&mut self, behavior: SyntaxBehavior)142     pub fn set_behavior(&mut self, behavior: SyntaxBehavior) {
143         let behavior = behavior.bits() as onig_sys::OnigSyntaxBehavior;
144         unsafe {
145             onig_sys::onig_set_syntax_behavior(&mut self.raw, behavior);
146         }
147     }
148 
149     /// Enable a given behaviour for this syntax
enable_behavior(&mut self, behavior: SyntaxBehavior)150     pub fn enable_behavior(&mut self, behavior: SyntaxBehavior) {
151         let behavior = self.behavior() | behavior;
152         self.set_behavior(behavior)
153     }
154 
155     /// Disable a given behaviour for this syntax
disable_behavior(&mut self, behavior: SyntaxBehavior)156     pub fn disable_behavior(&mut self, behavior: SyntaxBehavior) {
157         let behavior = self.behavior() & !behavior;
158         self.set_behavior(behavior)
159     }
160 
161     /// Retireve the syntax options for this syntax
options(&self) -> RegexOptions162     pub fn options(&self) -> RegexOptions {
163         RegexOptions::from_bits_truncate(unsafe {
164             onig_sys::onig_get_syntax_options(self.raw_mut())
165         })
166     }
167 
168     /// Replace the syntax options for this syntax
set_options(&mut self, options: RegexOptions)169     pub fn set_options(&mut self, options: RegexOptions) {
170         let options = options.bits() as onig_sys::OnigOptionType;
171         unsafe {
172             onig_sys::onig_set_syntax_options(&mut self.raw, options);
173         }
174     }
175 
176     /// Set a given meta character's state
177     ///
178     /// Arguments:
179     ///  - `what`: The meta character to update
180     ///  - `meta`: The value to set the meta character to
set_meta_char(&mut self, what: MetaCharType, meta: MetaChar)181     pub fn set_meta_char(&mut self, what: MetaCharType, meta: MetaChar) {
182         let what = what.bits();
183         let code = match meta {
184             MetaChar::Ineffective => onig_sys::ONIG_INEFFECTIVE_META_CHAR,
185             MetaChar::Character(char) => char as u32,
186         };
187         unsafe {
188             onig_sys::onig_set_meta_char(&mut self.raw, what, code);
189         }
190     }
191 
raw_mut(&self) -> *mut onig_sys::OnigSyntaxType192     fn raw_mut(&self) -> *mut onig_sys::OnigSyntaxType {
193         &self.raw as *const onig_sys::OnigSyntaxType as *mut onig_sys::OnigSyntaxType
194     }
195 }
196