quad_compat_rhai/packages/
fn_basic.rs1use crate::plugin::*;
2use crate::{def_package, FnPtr, ImmutableString, NativeCallContext};
3#[cfg(feature = "no_std")]
4use std::prelude::v1::*;
5
6def_package!(crate:BasicFnPackage:"Basic Fn functions.", lib, {
7 lib.standard = true;
8
9 combine_with_exported_module!(lib, "FnPtr", fn_ptr_functions);
10});
11
12#[export_module]
13mod fn_ptr_functions {
14 #[rhai_fn(name = "name", get = "name", pure)]
15 pub fn name(fn_ptr: &mut FnPtr) -> ImmutableString {
16 fn_ptr.fn_name_raw().into()
17 }
18
19 #[cfg(not(feature = "no_function"))]
20 #[rhai_fn(name = "is_anonymous", get = "is_anonymous", pure)]
21 pub fn is_anonymous(fn_ptr: &mut FnPtr) -> bool {
22 fn_ptr.is_anonymous()
23 }
24
25 #[cfg(not(feature = "no_function"))]
26 #[cfg(not(feature = "no_index"))]
27 #[cfg(not(feature = "no_object"))]
28 pub fn get_fn_metadata_list(ctx: NativeCallContext) -> crate::Array {
29 collect_fn_metadata(ctx)
30 }
31}
32
33#[cfg(not(feature = "no_function"))]
34#[cfg(not(feature = "no_index"))]
35#[cfg(not(feature = "no_object"))]
36fn collect_fn_metadata(ctx: NativeCallContext) -> crate::Array {
37 use crate::{ast::ScriptFnDef, Array, Identifier, Map};
38 use std::collections::BTreeSet;
39
40 fn make_metadata(
42 dict: &BTreeSet<Identifier>,
43 namespace: Option<Identifier>,
44 f: &ScriptFnDef,
45 ) -> Map {
46 const DICT: &str = "key exists";
47
48 let mut map = Map::new();
49
50 if let Some(ns) = namespace {
51 map.insert(dict.get("namespace").expect(DICT).clone(), ns.into());
52 }
53 map.insert(dict.get("name").expect(DICT).clone(), f.name.clone().into());
54 map.insert(
55 dict.get("access").expect(DICT).clone(),
56 match f.access {
57 FnAccess::Public => dict.get("public").expect(DICT).clone(),
58 FnAccess::Private => dict.get("private").expect(DICT).clone(),
59 }
60 .into(),
61 );
62 map.insert(
63 dict.get("is_anonymous").expect(DICT).clone(),
64 f.name.starts_with(crate::engine::FN_ANONYMOUS).into(),
65 );
66 map.insert(
67 dict.get("params").expect(DICT).clone(),
68 f.params
69 .iter()
70 .cloned()
71 .map(Into::<Dynamic>::into)
72 .collect::<Array>()
73 .into(),
74 );
75
76 map
77 }
78
79 let dict: BTreeSet<Identifier> = [
81 "namespace",
82 "name",
83 "access",
84 "public",
85 "private",
86 "is_anonymous",
87 "params",
88 ]
89 .iter()
90 .map(|&s| s.into())
91 .collect();
92
93 let mut _list = ctx.iter_namespaces().flat_map(Module::iter_script_fn).fold(
94 Array::new(),
95 |mut list, (_, _, _, _, f)| {
96 list.push(make_metadata(&dict, None, f).into());
97 list
98 },
99 );
100
101 #[cfg(not(feature = "no_module"))]
102 {
103 fn scan_module(
105 list: &mut Array,
106 dict: &BTreeSet<Identifier>,
107 namespace: Identifier,
108 module: &Module,
109 ) {
110 module.iter_script_fn().for_each(|(_, _, _, _, f)| {
111 list.push(make_metadata(dict, Some(namespace.clone()), f).into())
112 });
113 module.iter_sub_modules().for_each(|(ns, m)| {
114 let ns = format!(
115 "{}{}{}",
116 namespace,
117 crate::tokenizer::Token::DoubleColon.literal_syntax(),
118 ns
119 );
120 scan_module(list, dict, ns.into(), m.as_ref())
121 });
122 }
123
124 ctx.iter_imports_raw()
125 .for_each(|(ns, m)| scan_module(&mut _list, &dict, ns.clone(), m.as_ref()));
126 }
127
128 _list
129}