rhai/api/
options.rs

1//! Settings for [`Engine`]'s language options.
2
3use crate::Engine;
4use bitflags::bitflags;
5#[cfg(feature = "no_std")]
6use std::prelude::v1::*;
7
8bitflags! {
9    /// Bit-flags containing all language options for the [`Engine`].
10    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
11    pub struct LangOptions: u16 {
12        /// Is `if`-expression allowed?
13        const IF_EXPR = 0b_0000_0000_0001;
14        /// Is `switch` expression allowed?
15        const SWITCH_EXPR = 0b_0000_0000_0010;
16        /// Are loop expressions allowed?
17        const LOOP_EXPR = 0b_0000_0000_0100;
18        /// Is statement-expression allowed?
19        const STMT_EXPR = 0b_0000_0000_1000;
20        /// Is anonymous function allowed?
21        #[cfg(not(feature = "no_function"))]
22        const ANON_FN = 0b_0000_0001_0000;
23        /// Is looping allowed?
24        const LOOPING = 0b_0000_0010_0000;
25        /// Is variables shadowing allowed?
26        const SHADOWING = 0b_0000_0100_0000;
27        /// Strict variables mode?
28        const STRICT_VAR = 0b_0000_1000_0000;
29        /// Raise error if an object map property does not exist?
30        /// Returns `()` if `false`.
31        #[cfg(not(feature = "no_object"))]
32        const FAIL_ON_INVALID_MAP_PROPERTY = 0b_0001_0000_0000;
33        /// Fast operators mode?
34        const FAST_OPS = 0b_0010_0000_0000;
35    }
36}
37
38impl LangOptions {
39    /// Create a new [`LangOptions`] with default values.
40    #[inline(always)]
41    #[must_use]
42    pub const fn new() -> Self {
43        Self::from_bits_truncate(
44            Self::IF_EXPR.bits()
45                | Self::SWITCH_EXPR.bits()
46                | Self::LOOP_EXPR.bits()
47                | Self::STMT_EXPR.bits()
48                | Self::LOOPING.bits()
49                | Self::SHADOWING.bits()
50                | Self::FAST_OPS.bits()
51                | {
52                    #[cfg(not(feature = "no_function"))]
53                    {
54                        Self::ANON_FN.bits()
55                    }
56                    #[cfg(feature = "no_function")]
57                    {
58                        Self::empty().bits()
59                    }
60                },
61        )
62    }
63}
64
65impl Engine {
66    /// Is `if`-expression allowed?
67    /// Default is `true`.
68    #[inline(always)]
69    #[must_use]
70    pub const fn allow_if_expression(&self) -> bool {
71        self.options.intersects(LangOptions::IF_EXPR)
72    }
73    /// Set whether `if`-expression is allowed.
74    #[inline(always)]
75    pub fn set_allow_if_expression(&mut self, enable: bool) -> &mut Self {
76        self.options.set(LangOptions::IF_EXPR, enable);
77        self
78    }
79    /// Is `switch` expression allowed?
80    /// Default is `true`.
81    #[inline(always)]
82    #[must_use]
83    pub const fn allow_switch_expression(&self) -> bool {
84        self.options.intersects(LangOptions::SWITCH_EXPR)
85    }
86    /// Set whether `switch` expression is allowed.
87    #[inline(always)]
88    pub fn set_allow_switch_expression(&mut self, enable: bool) -> &mut Self {
89        self.options.set(LangOptions::SWITCH_EXPR, enable);
90        self
91    }
92    /// Are loop expressions allowed?
93    /// Default is `true`.
94    #[inline(always)]
95    #[must_use]
96    pub const fn allow_loop_expressions(&self) -> bool {
97        self.options.intersects(LangOptions::LOOP_EXPR)
98    }
99    /// Set whether loop expressions are allowed.
100    #[inline(always)]
101    pub fn set_allow_loop_expressions(&mut self, enable: bool) -> &mut Self {
102        self.options.set(LangOptions::LOOP_EXPR, enable);
103        self
104    }
105    /// Is statement-expression allowed?
106    /// Default is `true`.
107    #[inline(always)]
108    #[must_use]
109    pub const fn allow_statement_expression(&self) -> bool {
110        self.options.intersects(LangOptions::STMT_EXPR)
111    }
112    /// Set whether statement-expression is allowed.
113    #[inline(always)]
114    pub fn set_allow_statement_expression(&mut self, enable: bool) -> &mut Self {
115        self.options.set(LangOptions::STMT_EXPR, enable);
116        self
117    }
118    /// Is anonymous function allowed?
119    /// Default is `true`.
120    ///
121    /// Not available under `no_function`.
122    #[cfg(not(feature = "no_function"))]
123    #[inline(always)]
124    #[must_use]
125    pub const fn allow_anonymous_fn(&self) -> bool {
126        self.options.intersects(LangOptions::ANON_FN)
127    }
128    /// Set whether anonymous function is allowed.
129    ///
130    /// Not available under `no_function`.
131    #[cfg(not(feature = "no_function"))]
132    #[inline(always)]
133    pub fn set_allow_anonymous_fn(&mut self, enable: bool) -> &mut Self {
134        self.options.set(LangOptions::ANON_FN, enable);
135        self
136    }
137    /// Is looping allowed?
138    /// Default is `true`.
139    #[inline(always)]
140    #[must_use]
141    pub const fn allow_looping(&self) -> bool {
142        self.options.intersects(LangOptions::LOOPING)
143    }
144    /// Set whether looping is allowed.
145    #[inline(always)]
146    pub fn set_allow_looping(&mut self, enable: bool) -> &mut Self {
147        self.options.set(LangOptions::LOOPING, enable);
148        self
149    }
150    /// Is variables shadowing allowed?
151    /// Default is `true`.
152    #[inline(always)]
153    #[must_use]
154    pub const fn allow_shadowing(&self) -> bool {
155        self.options.intersects(LangOptions::SHADOWING)
156    }
157    /// Set whether variables shadowing is allowed.
158    #[inline(always)]
159    pub fn set_allow_shadowing(&mut self, enable: bool) -> &mut Self {
160        self.options.set(LangOptions::SHADOWING, enable);
161        self
162    }
163    /// Is strict variables mode enabled?
164    /// Default is `false`.
165    #[inline(always)]
166    #[must_use]
167    pub const fn strict_variables(&self) -> bool {
168        self.options.intersects(LangOptions::STRICT_VAR)
169    }
170    /// Set whether strict variables mode is enabled.
171    #[inline(always)]
172    pub fn set_strict_variables(&mut self, enable: bool) -> &mut Self {
173        self.options.set(LangOptions::STRICT_VAR, enable);
174        self
175    }
176    /// Raise error if an object map property does not exist?
177    /// Default is `false`.
178    ///
179    /// Not available under `no_object`.
180    #[cfg(not(feature = "no_object"))]
181    #[inline(always)]
182    #[must_use]
183    pub const fn fail_on_invalid_map_property(&self) -> bool {
184        self.options
185            .intersects(LangOptions::FAIL_ON_INVALID_MAP_PROPERTY)
186    }
187    /// Set whether to raise error if an object map property does not exist.
188    ///
189    /// Not available under `no_object`.
190    #[cfg(not(feature = "no_object"))]
191    #[inline(always)]
192    pub fn set_fail_on_invalid_map_property(&mut self, enable: bool) -> &mut Self {
193        self.options
194            .set(LangOptions::FAIL_ON_INVALID_MAP_PROPERTY, enable);
195        self
196    }
197    /// Is fast operators mode enabled?
198    /// Default is `false`.
199    #[inline(always)]
200    #[must_use]
201    pub const fn fast_operators(&self) -> bool {
202        self.options.intersects(LangOptions::FAST_OPS)
203    }
204    /// Set whether fast operators mode is enabled.
205    #[inline(always)]
206    pub fn set_fast_operators(&mut self, enable: bool) -> &mut Self {
207        self.options.set(LangOptions::FAST_OPS, enable);
208        self
209    }
210}