rhai/src/packages/fn_basic.rs

125 lines
3.7 KiB
Rust
Raw Normal View History

2020-08-14 12:58:34 +02:00
use crate::plugin::*;
2021-03-29 07:07:10 +02:00
use crate::{def_package, FnPtr, ImmutableString, NativeCallContext};
2021-04-17 09:15:54 +02:00
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
2020-11-23 12:11:32 +01:00
2020-06-25 12:07:57 +02:00
def_package!(crate:BasicFnPackage:"Basic Fn functions.", lib, {
2020-09-13 16:12:11 +02:00
combine_with_exported_module!(lib, "FnPtr", fn_ptr_functions);
2020-06-25 12:07:57 +02:00
});
2020-08-20 16:11:41 +02:00
#[export_module]
mod fn_ptr_functions {
#[rhai_fn(name = "name", get = "name", pure)]
2021-08-13 07:42:39 +02:00
pub fn name(fn_ptr: &mut FnPtr) -> ImmutableString {
fn_ptr.fn_name_raw().into()
2020-08-20 16:11:41 +02:00
}
2020-10-18 16:10:08 +02:00
#[cfg(not(feature = "no_function"))]
2020-11-23 12:11:32 +01:00
pub mod functions {
#[rhai_fn(name = "is_anonymous", get = "is_anonymous", pure)]
2021-08-13 07:42:39 +02:00
pub fn is_anonymous(fn_ptr: &mut FnPtr) -> bool {
fn_ptr.is_anonymous()
2020-10-18 16:10:08 +02:00
}
}
2020-11-23 12:11:32 +01:00
#[cfg(not(feature = "no_function"))]
#[cfg(not(feature = "no_index"))]
#[cfg(not(feature = "no_object"))]
pub mod functions_and_maps {
2021-03-07 15:10:54 +01:00
pub fn get_fn_metadata_list(ctx: NativeCallContext) -> crate::Array {
2020-11-23 12:11:32 +01:00
collect_fn_metadata(ctx)
}
}
}
#[cfg(not(feature = "no_function"))]
#[cfg(not(feature = "no_index"))]
#[cfg(not(feature = "no_object"))]
2021-03-07 15:10:54 +01:00
fn collect_fn_metadata(ctx: NativeCallContext) -> crate::Array {
2021-04-17 09:15:54 +02:00
use crate::{ast::ScriptFnDef, Array, Identifier, Map};
use std::collections::BTreeSet;
2021-03-07 15:10:54 +01:00
2020-11-23 12:11:32 +01:00
// Create a metadata record for a function.
fn make_metadata(
2021-03-29 05:36:02 +02:00
dict: &BTreeSet<Identifier>,
namespace: Option<Identifier>,
2020-11-25 02:36:06 +01:00
f: &ScriptFnDef,
2020-11-23 12:11:32 +01:00
) -> Map {
2021-05-22 13:14:24 +02:00
const DICT: &str = "never fails because the dictionary is pre-filled with all the keys";
2021-03-23 05:13:53 +01:00
let mut map = Map::new();
2020-11-23 12:11:32 +01:00
if let Some(ns) = namespace {
2021-07-24 08:11:16 +02:00
map.insert(dict.get("namespace").expect(DICT).clone(), ns.into());
2020-11-23 12:11:32 +01:00
}
2021-07-24 08:11:16 +02:00
map.insert(dict.get("name").expect(DICT).clone(), f.name.clone().into());
2020-11-23 12:11:32 +01:00
map.insert(
2021-07-24 08:11:16 +02:00
dict.get("access").expect(DICT).clone(),
2020-11-23 12:11:32 +01:00
match f.access {
2021-05-22 13:14:24 +02:00
FnAccess::Public => dict.get("public").expect(DICT).clone(),
FnAccess::Private => dict.get("private").expect(DICT).clone(),
2020-11-23 12:11:32 +01:00
}
.into(),
);
map.insert(
2021-07-24 08:11:16 +02:00
dict.get("is_anonymous").expect(DICT).clone(),
2020-11-23 12:11:32 +01:00
f.name.starts_with(crate::engine::FN_ANONYMOUS).into(),
);
map.insert(
2021-07-24 08:11:16 +02:00
dict.get("params").expect(DICT).clone(),
2020-11-23 12:11:32 +01:00
f.params
.iter()
.cloned()
.map(Into::<Dynamic>::into)
.collect::<Array>()
.into(),
);
2021-07-24 08:11:16 +02:00
map
2020-11-23 12:11:32 +01:00
}
// Intern strings
2021-03-29 05:36:02 +02:00
let dict: BTreeSet<Identifier> = [
2020-11-23 14:12:57 +01:00
"namespace",
"name",
"access",
"public",
"private",
"is_anonymous",
"params",
]
.iter()
2021-03-23 05:13:53 +01:00
.map(|&s| s.into())
.collect();
2020-11-23 12:11:32 +01:00
let mut list: Array = Default::default();
2021-03-03 15:49:57 +01:00
ctx.iter_namespaces()
2020-11-23 12:11:32 +01:00
.flat_map(|m| m.iter_script_fn())
.for_each(|(_, _, _, _, f)| list.push(make_metadata(&dict, None, f).into()));
2021-03-03 15:49:57 +01:00
#[cfg(not(feature = "no_module"))]
2021-03-07 15:10:54 +01:00
{
// Recursively scan modules for script-defined functions.
fn scan_module(
list: &mut Array,
2021-03-29 05:36:02 +02:00
dict: &BTreeSet<Identifier>,
namespace: Identifier,
2021-03-07 15:10:54 +01:00
module: &Module,
) {
module.iter_script_fn().for_each(|(_, _, _, _, f)| {
list.push(make_metadata(dict, Some(namespace.clone()), f).into())
});
module.iter_sub_modules().for_each(|(ns, m)| {
2021-03-17 06:30:47 +01:00
let ns = format!("{}::{}", namespace, ns);
scan_module(list, dict, ns.into(), m.as_ref())
2021-03-07 15:10:54 +01:00
});
}
ctx.iter_imports_raw()
.for_each(|(ns, m)| scan_module(&mut list, &dict, ns.clone(), m.as_ref()));
}
2020-11-23 12:11:32 +01:00
list
}