1use super::native::{FnAny, FnIterator, FnPlugin, SendSync};
4use crate::ast::{EncapsulatedEnviron, FnAccess};
5use crate::plugin::PluginFunc;
6use crate::Shared;
7use std::fmt;
8#[cfg(feature = "no_std")]
9use std::prelude::v1::*;
10
11#[derive(Clone)]
14#[non_exhaustive]
15pub enum RhaiFunc {
16 Pure {
18 func: Shared<FnAny>,
20 has_context: bool,
22 is_pure: bool,
24 is_volatile: bool,
28 },
29 Method {
32 func: Shared<FnAny>,
34 has_context: bool,
36 is_pure: bool,
38 is_volatile: bool,
42 },
43 Iterator {
45 func: Shared<FnIterator>,
47 },
48 Plugin {
50 func: Shared<FnPlugin>,
52 },
53 #[cfg(not(feature = "no_function"))]
55 Script {
56 fn_def: Shared<crate::ast::ScriptFuncDef>,
58 environ: Option<Shared<EncapsulatedEnviron>>,
60 },
61}
62
63impl fmt::Debug for RhaiFunc {
64 #[cold]
65 #[inline(never)]
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 match self {
68 Self::Pure { .. } => f.write_str("NativePureFunction"),
69 Self::Method { .. } => f.write_str("NativeMethod"),
70 Self::Iterator { .. } => f.write_str("NativeIterator"),
71 Self::Plugin { .. } => f.write_str("PluginFunction"),
72
73 #[cfg(not(feature = "no_function"))]
74 Self::Script { fn_def, .. } => fmt::Debug::fmt(fn_def, f),
75 }
76 }
77}
78
79impl fmt::Display for RhaiFunc {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 match self {
82 Self::Pure { .. } => f.write_str("NativePureFunction"),
83 Self::Method { .. } => f.write_str("NativeMethod"),
84 Self::Iterator { .. } => f.write_str("NativeIterator"),
85 Self::Plugin { .. } => f.write_str("PluginFunction"),
86
87 #[cfg(not(feature = "no_function"))]
88 Self::Script { fn_def, .. } => fmt::Display::fmt(fn_def, f),
89 }
90 }
91}
92
93impl RhaiFunc {
94 #[inline]
96 #[must_use]
97 pub fn is_pure(&self) -> bool {
98 match self {
99 Self::Pure { .. } => true,
100 Self::Method { is_pure, .. } => *is_pure,
101 Self::Iterator { .. } => true,
102
103 Self::Plugin { func, .. } => func.is_pure(),
104
105 #[cfg(not(feature = "no_function"))]
106 Self::Script { .. } => false,
107 }
108 }
109 #[inline]
111 #[must_use]
112 pub fn is_method(&self) -> bool {
113 match self {
114 Self::Method { .. } => true,
115 Self::Pure { .. } | Self::Iterator { .. } => false,
116
117 Self::Plugin { func, .. } => func.is_method_call(),
118
119 #[cfg(not(feature = "no_function"))]
120 Self::Script { .. } => false,
121 }
122 }
123 #[inline]
125 #[must_use]
126 pub const fn is_iter(&self) -> bool {
127 match self {
128 Self::Iterator { .. } => true,
129 Self::Pure { .. } | Self::Method { .. } | Self::Plugin { .. } => false,
130
131 #[cfg(not(feature = "no_function"))]
132 Self::Script { .. } => false,
133 }
134 }
135 #[inline]
137 #[must_use]
138 pub const fn is_script(&self) -> bool {
139 #[cfg(feature = "no_function")]
140 return false;
141
142 #[cfg(not(feature = "no_function"))]
143 match self {
144 Self::Script { .. } => true,
145 Self::Pure { .. }
146 | Self::Method { .. }
147 | Self::Iterator { .. }
148 | Self::Plugin { .. } => false,
149 }
150 }
151 #[inline]
153 #[must_use]
154 pub const fn is_plugin_fn(&self) -> bool {
155 match self {
156 Self::Plugin { .. } => true,
157 Self::Pure { .. } | Self::Method { .. } | Self::Iterator { .. } => false,
158
159 #[cfg(not(feature = "no_function"))]
160 Self::Script { .. } => false,
161 }
162 }
163 #[inline]
165 #[must_use]
166 pub const fn is_native(&self) -> bool {
167 #[cfg(feature = "no_function")]
168 return true;
169
170 #[cfg(not(feature = "no_function"))]
171 match self {
172 Self::Pure { .. }
173 | Self::Method { .. }
174 | Self::Plugin { .. }
175 | Self::Iterator { .. } => true,
176 Self::Script { .. } => false,
177 }
178 }
179 #[inline]
181 #[must_use]
182 pub fn has_context(&self) -> bool {
183 match self {
184 Self::Pure { has_context, .. } | Self::Method { has_context, .. } => *has_context,
185 Self::Plugin { func, .. } => func.has_context(),
186 Self::Iterator { .. } => false,
187 #[cfg(not(feature = "no_function"))]
188 Self::Script { .. } => false,
189 }
190 }
191 #[inline]
195 #[must_use]
196 pub fn is_volatile(&self) -> bool {
197 match self {
198 Self::Pure { is_volatile, .. } => *is_volatile,
199 Self::Method { is_volatile, .. } => *is_volatile,
200 Self::Iterator { .. } => true,
201
202 Self::Plugin { func, .. } => func.is_volatile(),
203
204 #[cfg(not(feature = "no_function"))]
206 Self::Script { .. } => true,
207 }
208 }
209 #[inline]
211 #[must_use]
212 pub fn access(&self) -> FnAccess {
213 #[cfg(feature = "no_function")]
214 return FnAccess::Public;
215
216 #[cfg(not(feature = "no_function"))]
217 match self {
218 Self::Plugin { .. }
219 | Self::Pure { .. }
220 | Self::Method { .. }
221 | Self::Iterator { .. } => FnAccess::Public,
222 Self::Script { fn_def, .. } => fn_def.access,
223 }
224 }
225 #[inline]
227 #[must_use]
228 pub fn get_native_fn(&self) -> Option<&Shared<FnAny>> {
229 match self {
230 Self::Pure { func, .. } | Self::Method { func, .. } => Some(func),
231 Self::Iterator { .. } | Self::Plugin { .. } => None,
232
233 #[cfg(not(feature = "no_function"))]
234 Self::Script { .. } => None,
235 }
236 }
237 #[cfg(not(feature = "no_function"))]
241 #[inline]
242 #[must_use]
243 pub const fn get_script_fn_def(&self) -> Option<&Shared<crate::ast::ScriptFuncDef>> {
244 match self {
245 Self::Pure { .. }
246 | Self::Method { .. }
247 | Self::Iterator { .. }
248 | Self::Plugin { .. } => None,
249 Self::Script { fn_def, .. } => Some(fn_def),
250 }
251 }
252 #[inline]
256 #[must_use]
257 pub fn get_encapsulated_environ(&self) -> Option<&EncapsulatedEnviron> {
258 match self {
259 Self::Pure { .. }
260 | Self::Method { .. }
261 | Self::Iterator { .. }
262 | Self::Plugin { .. } => None,
263
264 #[cfg(not(feature = "no_function"))]
265 Self::Script { environ, .. } => environ.as_deref(),
266 }
267 }
268 #[inline]
270 #[must_use]
271 pub fn get_iter_fn(&self) -> Option<&FnIterator> {
272 match self {
273 Self::Iterator { func, .. } => Some(&**func),
274 Self::Pure { .. } | Self::Method { .. } | Self::Plugin { .. } => None,
275
276 #[cfg(not(feature = "no_function"))]
277 Self::Script { .. } => None,
278 }
279 }
280 #[inline]
282 #[must_use]
283 pub fn get_plugin_fn(&self) -> Option<&Shared<FnPlugin>> {
284 match self {
285 Self::Plugin { func, .. } => Some(func),
286 Self::Pure { .. } | Self::Method { .. } | Self::Iterator { .. } => None,
287
288 #[cfg(not(feature = "no_function"))]
289 Self::Script { .. } => None,
290 }
291 }
292}
293
294#[cfg(not(feature = "no_function"))]
295impl From<crate::ast::ScriptFuncDef> for RhaiFunc {
296 #[inline(always)]
297 fn from(fn_def: crate::ast::ScriptFuncDef) -> Self {
298 Self::Script {
299 fn_def: fn_def.into(),
300 environ: None,
301 }
302 }
303}
304
305#[cfg(not(feature = "no_function"))]
306impl From<Shared<crate::ast::ScriptFuncDef>> for RhaiFunc {
307 #[inline(always)]
308 fn from(fn_def: Shared<crate::ast::ScriptFuncDef>) -> Self {
309 Self::Script {
310 fn_def,
311 environ: None,
312 }
313 }
314}
315
316impl<T: PluginFunc + 'static + SendSync> From<T> for RhaiFunc {
317 #[inline(always)]
318 fn from(func: T) -> Self {
319 Self::Plugin {
320 func: Shared::new(func),
321 }
322 }
323}
324
325impl From<Shared<FnPlugin>> for RhaiFunc {
326 #[inline(always)]
327 fn from(func: Shared<FnPlugin>) -> Self {
328 Self::Plugin { func }
329 }
330}