Skip to main content

sema_stdlib/
lib.rs

1#![allow(clippy::mutable_key_type, clippy::cloned_ref_to_slice_refs)]
2mod arithmetic;
3mod bitwise;
4mod bytevector;
5mod comparison;
6mod context;
7mod crypto;
8mod csv_ops;
9mod datetime;
10#[cfg(not(target_arch = "wasm32"))]
11mod http;
12#[cfg(not(target_arch = "wasm32"))]
13mod io;
14pub(crate) mod json;
15#[cfg(not(target_arch = "wasm32"))]
16mod kv;
17mod list;
18mod map;
19mod math;
20mod meta;
21#[cfg(not(target_arch = "wasm32"))]
22mod pdf;
23mod predicates;
24mod regex_ops;
25mod string;
26#[cfg(not(target_arch = "wasm32"))]
27mod system;
28#[cfg(not(target_arch = "wasm32"))]
29mod terminal;
30mod text;
31
32use sema_core::{Caps, Env, Sandbox, Value};
33
34pub fn register_stdlib(env: &Env, sandbox: &Sandbox) {
35    arithmetic::register(env);
36    comparison::register(env);
37    context::register(env);
38    list::register(env);
39    string::register(env);
40    predicates::register(env);
41    map::register(env);
42    #[cfg(not(target_arch = "wasm32"))]
43    io::register(env, sandbox);
44    math::register(env);
45    #[cfg(not(target_arch = "wasm32"))]
46    system::register(env, sandbox);
47    json::register(env);
48    meta::register(env);
49    regex_ops::register(env);
50    #[cfg(not(target_arch = "wasm32"))]
51    http::register(env, sandbox);
52    bitwise::register(env);
53    crypto::register(env);
54    datetime::register(env);
55    csv_ops::register(env);
56    bytevector::register(env);
57    #[cfg(not(target_arch = "wasm32"))]
58    terminal::register(env);
59    text::register(env);
60    #[cfg(not(target_arch = "wasm32"))]
61    kv::register(env, sandbox);
62    #[cfg(not(target_arch = "wasm32"))]
63    pdf::register(env, sandbox);
64}
65
66fn register_fn_gated(
67    env: &Env,
68    sandbox: &Sandbox,
69    cap: Caps,
70    name: &str,
71    f: impl Fn(&[Value]) -> Result<Value, sema_core::SemaError> + 'static,
72) {
73    if sandbox.is_unrestricted() {
74        register_fn(env, name, f);
75    } else {
76        let sandbox = sandbox.clone();
77        let fn_name = name.to_string();
78        register_fn(env, name, move |args| {
79            sandbox.check(cap, &fn_name)?;
80            f(args)
81        });
82    }
83}
84
85fn register_fn(
86    env: &Env,
87    name: &str,
88    f: impl Fn(&[Value]) -> Result<Value, sema_core::SemaError> + 'static,
89) {
90    env.set(
91        sema_core::intern(name),
92        Value::native_fn(sema_core::NativeFn::simple(name, f)),
93    );
94}