1#![cfg(not(feature = "unchecked"))]
3
4use crate::Engine;
5use std::num::{NonZeroU64, NonZeroUsize};
6#[cfg(feature = "no_std")]
7use std::prelude::v1::*;
8
9#[cfg(debug_assertions)]
10pub mod default_limits {
11 #[cfg(not(feature = "no_function"))]
15 pub const MAX_CALL_STACK_DEPTH: usize = 8;
16 pub const MAX_EXPR_DEPTH: usize = 32;
18 #[cfg(not(feature = "no_function"))]
22 pub const MAX_FUNCTION_EXPR_DEPTH: usize = 16;
23}
24#[cfg(not(debug_assertions))]
25pub mod default_limits {
26 #[cfg(not(feature = "no_function"))]
30 pub const MAX_CALL_STACK_DEPTH: usize = 64;
31 pub const MAX_EXPR_DEPTH: usize = 64;
33 #[cfg(not(feature = "no_function"))]
37 pub const MAX_FUNCTION_EXPR_DEPTH: usize = 32;
38}
39
40#[derive(Debug, Clone, Eq, PartialEq, Hash)]
44pub struct Limits {
45 #[cfg(not(feature = "no_function"))]
51 pub call_stack_depth: usize,
52 pub expr_depth: Option<NonZeroUsize>,
54 #[cfg(not(feature = "no_function"))]
58 pub function_expr_depth: Option<NonZeroUsize>,
59 pub num_operations: Option<NonZeroU64>,
61 pub num_variables: usize,
65 #[cfg(not(feature = "no_function"))]
71 pub num_functions: usize,
72 #[cfg(not(feature = "no_module"))]
78 pub num_modules: usize,
79 pub string_len: Option<NonZeroUsize>,
81 #[cfg(not(feature = "no_index"))]
85 pub array_size: Option<NonZeroUsize>,
86 #[cfg(not(feature = "no_object"))]
90 pub map_size: Option<NonZeroUsize>,
91}
92
93impl Limits {
94 #[inline]
98 pub const fn new() -> Self {
99 Self {
100 #[cfg(not(feature = "no_function"))]
101 call_stack_depth: default_limits::MAX_CALL_STACK_DEPTH,
102 expr_depth: NonZeroUsize::new(default_limits::MAX_EXPR_DEPTH),
103 #[cfg(not(feature = "no_function"))]
104 function_expr_depth: NonZeroUsize::new(default_limits::MAX_FUNCTION_EXPR_DEPTH),
105 num_operations: None,
106 num_variables: usize::MAX,
107 #[cfg(not(feature = "no_function"))]
108 num_functions: usize::MAX,
109 #[cfg(not(feature = "no_module"))]
110 num_modules: usize::MAX,
111 string_len: None,
112 #[cfg(not(feature = "no_index"))]
113 array_size: None,
114 #[cfg(not(feature = "no_object"))]
115 map_size: None,
116 }
117 }
118}
119
120impl Default for Limits {
121 #[inline(always)]
122 fn default() -> Self {
123 Self::new()
124 }
125}
126
127impl Engine {
128 #[inline(always)]
130 pub(crate) const fn has_data_size_limit(&self) -> bool {
131 self.limits.string_len.is_some()
132 || {
133 #[cfg(not(feature = "no_index"))]
134 {
135 self.limits.array_size.is_some()
136 }
137 #[cfg(feature = "no_index")]
138 false
139 }
140 || {
141 #[cfg(not(feature = "no_object"))]
142 {
143 self.limits.map_size.is_some()
144 }
145 #[cfg(feature = "no_object")]
146 false
147 }
148 }
149 #[cfg(not(feature = "no_function"))]
154 #[inline(always)]
155 pub fn set_max_call_levels(&mut self, levels: usize) -> &mut Self {
156 self.limits.call_stack_depth = levels;
157 self
158 }
159 #[cfg(not(feature = "no_function"))]
163 #[inline(always)]
164 #[must_use]
165 pub const fn max_call_levels(&self) -> usize {
166 self.limits.call_stack_depth
167 }
168 #[inline(always)]
173 pub fn set_max_operations(&mut self, operations: u64) -> &mut Self {
174 self.limits.num_operations = NonZeroU64::new(operations);
175 self
176 }
177 #[inline]
181 #[must_use]
182 pub const fn max_operations(&self) -> u64 {
183 match self.limits.num_operations {
184 Some(n) => n.get(),
185 None => 0,
186 }
187 }
188 #[inline(always)]
192 pub fn set_max_variables(&mut self, variables: usize) -> &mut Self {
193 self.limits.num_variables = variables;
194 self
195 }
196 #[inline(always)]
200 #[must_use]
201 pub const fn max_variables(&self) -> usize {
202 self.limits.num_variables
203 }
204 #[cfg(not(feature = "no_function"))]
208 #[inline(always)]
209 pub fn set_max_functions(&mut self, functions: usize) -> &mut Self {
210 self.limits.num_functions = functions;
211 self
212 }
213 #[cfg(not(feature = "no_function"))]
217 #[inline(always)]
218 #[must_use]
219 pub const fn max_functions(&self) -> usize {
220 self.limits.num_functions
221 }
222 #[cfg(not(feature = "no_module"))]
226 #[inline(always)]
227 pub fn set_max_modules(&mut self, modules: usize) -> &mut Self {
228 self.limits.num_modules = modules;
229 self
230 }
231 #[cfg(not(feature = "no_module"))]
235 #[inline(always)]
236 #[must_use]
237 pub const fn max_modules(&self) -> usize {
238 self.limits.num_modules
239 }
240 #[inline(always)]
244 pub fn set_max_expr_depths(
245 &mut self,
246 max_expr_depth: usize,
247 #[cfg(not(feature = "no_function"))] max_function_expr_depth: usize,
248 ) -> &mut Self {
249 self.limits.expr_depth = NonZeroUsize::new(max_expr_depth);
250 #[cfg(not(feature = "no_function"))]
251 {
252 self.limits.function_expr_depth = NonZeroUsize::new(max_function_expr_depth);
253 }
254 self
255 }
256 #[inline]
260 #[must_use]
261 pub const fn max_expr_depth(&self) -> usize {
262 match self.limits.expr_depth {
263 Some(n) => n.get(),
264 None => 0,
265 }
266 }
267 #[inline]
271 #[must_use]
272 pub const fn max_function_expr_depth(&self) -> usize {
273 #[cfg(not(feature = "no_function"))]
274 return match self.limits.function_expr_depth {
275 Some(n) => n.get(),
276 None => 0,
277 };
278 #[cfg(feature = "no_function")]
279 return 0;
280 }
281 #[inline(always)]
285 pub fn set_max_string_size(&mut self, max_len: usize) -> &mut Self {
286 self.limits.string_len = NonZeroUsize::new(max_len);
287 self
288 }
289 #[inline]
293 #[must_use]
294 pub const fn max_string_size(&self) -> usize {
295 match self.limits.string_len {
296 Some(n) => n.get(),
297 None => 0,
298 }
299 }
300 #[cfg(not(feature = "no_index"))]
304 #[inline(always)]
305 pub fn set_max_array_size(&mut self, max_size: usize) -> &mut Self {
306 self.limits.array_size = NonZeroUsize::new(max_size);
307 self
308 }
309 #[inline]
313 #[must_use]
314 pub const fn max_array_size(&self) -> usize {
315 #[cfg(not(feature = "no_index"))]
316 return match self.limits.array_size {
317 Some(n) => n.get(),
318 None => 0,
319 };
320 #[cfg(feature = "no_index")]
321 return 0;
322 }
323 #[cfg(not(feature = "no_object"))]
327 #[inline(always)]
328 pub fn set_max_map_size(&mut self, max_size: usize) -> &mut Self {
329 self.limits.map_size = NonZeroUsize::new(max_size);
330 self
331 }
332 #[inline]
336 #[must_use]
337 pub const fn max_map_size(&self) -> usize {
338 #[cfg(not(feature = "no_object"))]
339 return match self.limits.map_size {
340 Some(n) => n.get(),
341 None => 0,
342 };
343 #[cfg(feature = "no_object")]
344 return 0;
345 }
346}