Switch from Boa to QuickJS for JavaScript runtime
This commit is contained in:
parent
6ef120f7ce
commit
338bf3e142
11 changed files with 534 additions and 483 deletions
331
Cargo.lock
generated
331
Cargo.lock
generated
|
@ -8,17 +8,6 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||
dependencies = [
|
||||
"getrandom 0.2.7",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
|
@ -286,70 +275,6 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "boa_engine"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06d42e34ff7c02423cb5248bc67021f13f2bb7aec22de7ab351a6a4e31ec6d9"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"boa_gc",
|
||||
"boa_interner",
|
||||
"boa_profiler",
|
||||
"boa_unicode",
|
||||
"chrono",
|
||||
"dyn-clone",
|
||||
"fast-float",
|
||||
"gc",
|
||||
"indexmap",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"rand 0.8.5",
|
||||
"regress",
|
||||
"rustc-hash",
|
||||
"ryu-js",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tap",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "boa_gc"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a1167c469e96484d0f1d73d2a1ae5e44983aa49a32630d76f5a555116b18204"
|
||||
dependencies = [
|
||||
"gc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "boa_interner"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77a8a4c15b4b0e86daa063c7123da11f8e41ecdc91fc086d1fd8898670b2f40e"
|
||||
dependencies = [
|
||||
"gc",
|
||||
"string-interner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "boa_profiler"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28bd5912d57793f8fd312ce63eaedd34fa6ff5fe759be508d3d2455905b0880a"
|
||||
|
||||
[[package]]
|
||||
name = "boa_unicode"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90b9a73ca3f2bdd98e3e132e3c93684d9ab682ed5a3cad8be6b87c38d7f349e6"
|
||||
dependencies = [
|
||||
"unicode-general-category",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "boringssl-src"
|
||||
version = "0.2.0"
|
||||
|
@ -601,6 +526,41 @@ dependencies = [
|
|||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "649c91bc01e8b1eac09fb91e8dbc7d517684ca6be8ebc75bb9cafc894f9fdb6f"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive-new"
|
||||
version = "0.5.9"
|
||||
|
@ -648,12 +608,6 @@ dependencies = [
|
|||
"urlencoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28"
|
||||
|
||||
[[package]]
|
||||
name = "echodb"
|
||||
version = "0.3.0"
|
||||
|
@ -708,12 +662,6 @@ dependencies = [
|
|||
"rand 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fast-float"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.7.0"
|
||||
|
@ -764,6 +712,19 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.10.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ceeb589a3157cac0ab8cc585feb749bd2cea5cb55a6ee802ad72d9fd38303da"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"nanorand",
|
||||
"pin-project",
|
||||
"spin 0.9.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
@ -922,27 +883,6 @@ dependencies = [
|
|||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gc"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3edaac0f5832202ebc99520cb77c932248010c4645d20be1dc62d6579f5b3752"
|
||||
dependencies = [
|
||||
"gc_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gc_derive"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60df8444f094ff7885631d80e78eb7d88c3c2361a98daaabb06256e4500db941"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.5"
|
||||
|
@ -1008,8 +948,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1102,9 +1044,6 @@ name = "hashbrown"
|
|||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "headers"
|
||||
|
@ -1248,6 +1187,12 @@ dependencies = [
|
|||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.3"
|
||||
|
@ -1538,6 +1483,15 @@ dependencies = [
|
|||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nanorand"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
||||
dependencies = [
|
||||
"getrandom 0.2.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.10"
|
||||
|
@ -1600,7 +1554,6 @@ dependencies = [
|
|||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1860,6 +1813,40 @@ version = "0.2.16"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.39"
|
||||
|
@ -2147,13 +2134,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
||||
|
||||
[[package]]
|
||||
name = "regress"
|
||||
version = "0.4.1"
|
||||
name = "relative-path"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a92ff21fe8026ce3f2627faaf43606f0b67b014dbc9ccf027181a804f75d92e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
checksum = "b4e112eddc95bbf25365df3b5414354ad2fe7ee465eddb9965a515faf8c3b6d9"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
|
@ -2280,6 +2264,58 @@ version = "0.2.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5864e7ef1a6b7bcf1d6ca3f655e65e724ed3b52546a0d0a663c991522f552ea"
|
||||
|
||||
[[package]]
|
||||
name = "rquickjs"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "989910af47b3f21c95205a1e1974bfb0f460e5492f469631297cc44c3340967e"
|
||||
dependencies = [
|
||||
"rquickjs-core",
|
||||
"rquickjs-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rquickjs-core"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78ca2361848dddf910c27296d98bd62be9467d1d1d703eeead8c732adbd4e32"
|
||||
dependencies = [
|
||||
"async-task",
|
||||
"chrono",
|
||||
"flume",
|
||||
"futures-lite",
|
||||
"pin-project-lite",
|
||||
"relative-path",
|
||||
"rquickjs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rquickjs-macro"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61e2079f08cea21359618d33146cee860fc362857b8b16357c8c444ca3ae6104"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"indexmap",
|
||||
"proc-macro-crate",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rquickjs-core",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rquickjs-sys"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "263a9a14fc68f2f3403c67e94e5def69af60afbcf7914d2a7fb8f9e17027fa25"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rstar"
|
||||
version = "0.9.3"
|
||||
|
@ -2334,12 +2370,6 @@ version = "1.0.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
|
||||
|
||||
[[package]]
|
||||
name = "ryu-js"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6518fc26bced4d53678a22d6e423e9d8716377def84545fe328236e3af070e7f"
|
||||
|
||||
[[package]]
|
||||
name = "safemem"
|
||||
version = "0.3.3"
|
||||
|
@ -2623,17 +2653,6 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "string-interner"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e2531d8525b29b514d25e275a43581320d587b86db302b9a7e464bac579648"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
|
@ -2683,14 +2702,12 @@ dependencies = [
|
|||
"async-executor",
|
||||
"async-recursion",
|
||||
"bigdecimal",
|
||||
"boa_engine",
|
||||
"chrono",
|
||||
"deunicode",
|
||||
"dmp",
|
||||
"echodb",
|
||||
"futures 0.3.21",
|
||||
"fuzzy-matcher",
|
||||
"gc",
|
||||
"geo",
|
||||
"indxdb",
|
||||
"lexical-sort",
|
||||
|
@ -2703,6 +2720,7 @@ dependencies = [
|
|||
"rand 0.8.5",
|
||||
"regex",
|
||||
"rmp-serde",
|
||||
"rquickjs",
|
||||
"scrypt",
|
||||
"serde",
|
||||
"sha-1 0.10.0",
|
||||
|
@ -2739,24 +2757,6 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
version = "0.12.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.3.0"
|
||||
|
@ -3047,6 +3047,15 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.1"
|
||||
|
@ -3140,12 +3149,6 @@ version = "0.3.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-general-category"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1218098468b8085b19a2824104c70d976491d247ce194bbd9dc77181150cdfd6"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.1"
|
||||
|
@ -3167,12 +3170,6 @@ version = "1.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
|
|
|
@ -12,13 +12,12 @@ kv-tikv = ["tikv"]
|
|||
kv-echodb = ["echodb"]
|
||||
kv-indxdb = ["indxdb"]
|
||||
kv-yokudb = []
|
||||
scripting = ["boa", "gc"]
|
||||
scripting = ["js", "executor"]
|
||||
|
||||
[dependencies]
|
||||
argon2 = "0.4.1"
|
||||
async-recursion = "1.0.0"
|
||||
bigdecimal = { version = "0.3.0", features = ["serde", "string-only"] }
|
||||
boa = { version = "0.15.0", package = "boa_engine", optional = true }
|
||||
channel = { version = "1.6.1", package = "async-channel" }
|
||||
chrono = { version = "0.4.19", features = ["serde"] }
|
||||
derive = { version = "0.3.0", package = "surrealdb-derive" }
|
||||
|
@ -28,9 +27,9 @@ echodb = { version = "0.3.0", optional = true }
|
|||
executor = { version = "1.4.1", package = "async-executor", optional = true }
|
||||
futures = "0.3.21"
|
||||
fuzzy-matcher = "0.3.7"
|
||||
gc = { version = "0.4.1", optional = true }
|
||||
geo = { version = "0.22.0", features = ["use-serde"] }
|
||||
indxdb = { version = "0.2.0", optional = true }
|
||||
js = { version = "0.1.6", package = "rquickjs", features = ["chrono", "classes", "futures", "macro", "properties", "parallel"], optional = true }
|
||||
lexical-sort = "0.3.1"
|
||||
log = "0.4.17"
|
||||
md-5 = "0.10.1"
|
||||
|
|
|
@ -1,313 +0,0 @@
|
|||
#![cfg(feature = "scripting")]
|
||||
|
||||
use crate::ctx::Context;
|
||||
use crate::err::Error;
|
||||
use crate::sql::array::Array;
|
||||
use crate::sql::datetime::Datetime;
|
||||
use crate::sql::duration::Duration;
|
||||
use crate::sql::number::Number;
|
||||
use crate::sql::object::Object;
|
||||
use crate::sql::thing::Thing;
|
||||
use crate::sql::value::Value;
|
||||
use bigdecimal::ToPrimitive;
|
||||
use boa::builtins::date::Date;
|
||||
use boa::class::Class;
|
||||
use boa::class::ClassBuilder;
|
||||
use boa::object::JsArray;
|
||||
use boa::object::JsObject;
|
||||
use boa::object::ObjectData;
|
||||
use boa::object::ObjectKind;
|
||||
use boa::property::Attribute;
|
||||
use boa::Context as Boa;
|
||||
use boa::JsResult;
|
||||
use boa::JsString;
|
||||
use boa::JsValue;
|
||||
use chrono::Datelike;
|
||||
use chrono::Timelike;
|
||||
use gc::Finalize;
|
||||
use gc::Trace;
|
||||
|
||||
#[derive(Debug, Trace, Finalize)]
|
||||
pub struct JsDuration {
|
||||
value: String,
|
||||
}
|
||||
|
||||
impl Class for JsDuration {
|
||||
const NAME: &'static str = "Duration";
|
||||
const LENGTH: usize = 1;
|
||||
fn constructor(_this: &JsValue, args: &[JsValue], ctx: &mut Boa) -> JsResult<Self> {
|
||||
Ok(JsDuration {
|
||||
value: args.get(0).cloned().unwrap_or_default().to_string(ctx)?.to_string(),
|
||||
})
|
||||
}
|
||||
fn init(class: &mut ClassBuilder) -> JsResult<()> {
|
||||
class.method("value", 0, |this, _, _| {
|
||||
if let Some(v) = this.as_object() {
|
||||
if let Some(v) = v.downcast_ref::<JsDuration>() {
|
||||
return Ok(v.value.clone().into());
|
||||
}
|
||||
}
|
||||
Ok(JsValue::Undefined)
|
||||
});
|
||||
class.method("toString", 0, |this, _, _| {
|
||||
if let Some(v) = this.as_object() {
|
||||
if let Some(v) = v.downcast_ref::<JsDuration>() {
|
||||
return Ok(v.value.clone().into());
|
||||
}
|
||||
}
|
||||
Ok(JsValue::Undefined)
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Trace, Finalize)]
|
||||
pub struct JsRecord {
|
||||
tb: String,
|
||||
id: String,
|
||||
}
|
||||
|
||||
impl Class for JsRecord {
|
||||
const NAME: &'static str = "Record";
|
||||
const LENGTH: usize = 2;
|
||||
fn constructor(_this: &JsValue, args: &[JsValue], ctx: &mut Boa) -> JsResult<Self> {
|
||||
Ok(JsRecord {
|
||||
tb: args.get(0).cloned().unwrap_or_default().to_string(ctx)?.to_string(),
|
||||
id: args.get(1).cloned().unwrap_or_default().to_string(ctx)?.to_string(),
|
||||
})
|
||||
}
|
||||
fn init(class: &mut ClassBuilder) -> JsResult<()> {
|
||||
class.method("tb", 0, |this, _, _| {
|
||||
if let Some(v) = this.as_object() {
|
||||
if let Some(v) = v.downcast_ref::<JsRecord>() {
|
||||
return Ok(v.tb.clone().into());
|
||||
}
|
||||
}
|
||||
Ok(JsValue::Undefined)
|
||||
});
|
||||
class.method("id", 0, |this, _, _| {
|
||||
if let Some(v) = this.as_object() {
|
||||
if let Some(v) = v.downcast_ref::<JsRecord>() {
|
||||
return Ok(v.id.clone().into());
|
||||
}
|
||||
}
|
||||
Ok(JsValue::Undefined)
|
||||
});
|
||||
class.method("toString", 0, |this, _, _| {
|
||||
if let Some(v) = this.as_object() {
|
||||
if let Some(v) = v.downcast_ref::<JsRecord>() {
|
||||
return Ok(format!("{}:{}", v.tb, v.id).into());
|
||||
}
|
||||
}
|
||||
Ok(JsValue::Undefined)
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(
|
||||
ctx: &Context<'_>,
|
||||
src: &str,
|
||||
arg: Vec<Value>,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Check the context
|
||||
let _ = ctx.check()?;
|
||||
// Create an execution context
|
||||
let mut ctx = Boa::default();
|
||||
// Convert the arguments to JavaScript
|
||||
let args = JsValue::from(Value::from(arg));
|
||||
// Convert the current document to JavaScript
|
||||
let this = doc.map_or(JsValue::Undefined, JsValue::from);
|
||||
// Create the main function structure
|
||||
let src = format!("(function() {{ {} }}).apply(self, args)", src);
|
||||
// Register the current document as a global object
|
||||
ctx.register_global_property("self", this, Attribute::default());
|
||||
// Register the current document as a global object
|
||||
ctx.register_global_property("args", args, Attribute::default());
|
||||
// Register the JsDuration type as a global class
|
||||
ctx.register_global_class::<JsDuration>().unwrap();
|
||||
// Register the JsRecord type as a global class
|
||||
ctx.register_global_class::<JsRecord>().unwrap();
|
||||
// Attempt to execute the script
|
||||
match ctx.eval(src.as_bytes()) {
|
||||
// The script executed successfully
|
||||
Ok(v) => Ok(v.into()),
|
||||
// There was an error running the script
|
||||
Err(e) => Err(Error::InvalidScript {
|
||||
message: e.display().to_string(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Datetime> for Date {
|
||||
fn from(v: &Datetime) -> Self {
|
||||
let mut obj = Self::default();
|
||||
obj.set_components(
|
||||
true,
|
||||
Some(v.year() as f64),
|
||||
Some(v.month0() as f64),
|
||||
Some(v.day() as f64),
|
||||
Some(v.hour() as f64),
|
||||
Some(v.minute() as f64),
|
||||
Some(v.second() as f64),
|
||||
Some((v.nanosecond() / 1_000_000) as f64),
|
||||
);
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Value> for JsValue {
|
||||
fn from(v: Value) -> Self {
|
||||
JsValue::from(&v)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Value> for JsValue {
|
||||
fn from(v: &Value) -> Self {
|
||||
match v {
|
||||
Value::Null => JsValue::Null,
|
||||
Value::Void => JsValue::Undefined,
|
||||
Value::None => JsValue::Undefined,
|
||||
Value::True => JsValue::Boolean(true),
|
||||
Value::False => JsValue::Boolean(false),
|
||||
Value::Strand(v) => JsValue::String(v.as_str().into()),
|
||||
Value::Number(Number::Int(v)) => JsValue::Integer(*v as i32),
|
||||
Value::Number(Number::Float(v)) => JsValue::Rational(*v as f64),
|
||||
Value::Number(Number::Decimal(v)) => match v.is_integer() {
|
||||
true => JsValue::BigInt(v.to_i64().unwrap_or_default().into()),
|
||||
false => JsValue::Rational(v.to_f64().unwrap_or_default()),
|
||||
},
|
||||
Value::Datetime(v) => JsValue::from(JsObject::from_proto_and_data(
|
||||
Boa::default().intrinsics().constructors().date().prototype(),
|
||||
ObjectData::date(v.into()),
|
||||
)),
|
||||
Value::Duration(v) => JsValue::from(JsObject::from_proto_and_data(
|
||||
Boa::default().intrinsics().constructors().object().prototype(),
|
||||
ObjectData::native_object(Box::new(JsDuration {
|
||||
value: v.to_string(),
|
||||
})),
|
||||
)),
|
||||
Value::Thing(v) => JsValue::from(JsObject::from_proto_and_data(
|
||||
Boa::default().intrinsics().constructors().object().prototype(),
|
||||
ObjectData::native_object(Box::new(JsRecord {
|
||||
tb: v.tb.to_string(),
|
||||
id: v.id.to_string(),
|
||||
})),
|
||||
)),
|
||||
Value::Array(v) => {
|
||||
let ctx = &mut Boa::default();
|
||||
let arr = JsArray::new(ctx);
|
||||
for v in v.iter() {
|
||||
arr.push(JsValue::from(v), ctx).unwrap();
|
||||
}
|
||||
JsValue::from(arr)
|
||||
}
|
||||
Value::Object(v) => {
|
||||
let ctx = &mut Boa::default();
|
||||
let obj = JsObject::default();
|
||||
for (k, v) in v.iter() {
|
||||
let k = JsString::from(k.as_str());
|
||||
let v = JsValue::from(v);
|
||||
obj.set(k, v, true, ctx).unwrap();
|
||||
}
|
||||
JsValue::from(obj)
|
||||
}
|
||||
_ => JsValue::Null,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<JsValue> for Value {
|
||||
fn from(v: JsValue) -> Self {
|
||||
Value::from(&v)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&JsValue> for Value {
|
||||
fn from(v: &JsValue) -> Self {
|
||||
match v {
|
||||
JsValue::Null => Value::Null,
|
||||
JsValue::Undefined => Value::None,
|
||||
JsValue::Boolean(v) => Value::from(*v),
|
||||
JsValue::String(v) => Value::from(v.as_str()),
|
||||
JsValue::Integer(v) => Value::from(Number::Int(*v as i64)),
|
||||
JsValue::Rational(v) => Value::from(Number::Float(*v as f64)),
|
||||
JsValue::BigInt(v) => Value::from(Number::from(v.clone().to_string())),
|
||||
JsValue::Object(v) => {
|
||||
// Check to see if this object is a duration
|
||||
if v.is::<JsDuration>() {
|
||||
if let Some(v) = v.downcast_ref::<JsDuration>() {
|
||||
let v = v.value.clone();
|
||||
return Duration::from(v).into();
|
||||
}
|
||||
}
|
||||
// Check to see if this object is a record
|
||||
if v.is::<JsRecord>() {
|
||||
if let Some(v) = v.downcast_ref::<JsRecord>() {
|
||||
let v = (v.tb.clone(), v.id.clone());
|
||||
return Thing::from(v).into();
|
||||
}
|
||||
}
|
||||
// Check to see if this object is a date
|
||||
if let Some(v) = v.borrow().as_date() {
|
||||
if let Some(v) = v.to_utc() {
|
||||
return Datetime::from(v).into();
|
||||
}
|
||||
}
|
||||
// Get a borrowed reference to the object
|
||||
let o = v.borrow();
|
||||
// Check to see if this is a normal type
|
||||
match o.kind() {
|
||||
// This object is a Javascript Array
|
||||
ObjectKind::Array => {
|
||||
let mut x = Array::default();
|
||||
let ctx = &mut Boa::default();
|
||||
let len = v.get("length", ctx).unwrap().to_u32(ctx).unwrap();
|
||||
for i in 0..len {
|
||||
let v = o.properties().get(&i.into()).unwrap();
|
||||
if let Some(v) = v.value() {
|
||||
let v = Value::from(v);
|
||||
x.push(v);
|
||||
}
|
||||
}
|
||||
x.into()
|
||||
}
|
||||
// This object is a Javascript Object
|
||||
ObjectKind::Ordinary => {
|
||||
let mut x = Object::default();
|
||||
for (k, v) in o.properties().iter() {
|
||||
if let Some(v) = v.value() {
|
||||
let k = k.to_string();
|
||||
let v = Value::from(v);
|
||||
x.insert(k, v);
|
||||
}
|
||||
}
|
||||
x.into()
|
||||
}
|
||||
// This object is a Javascript Map
|
||||
ObjectKind::Map(v) => {
|
||||
let mut x = Object::default();
|
||||
for (k, v) in v.iter() {
|
||||
let k = Value::from(k).as_string();
|
||||
let v = Value::from(v);
|
||||
x.insert(k, v);
|
||||
}
|
||||
x.into()
|
||||
}
|
||||
// This object is a Javascript Set
|
||||
ObjectKind::Set(v) => {
|
||||
let mut x = Array::default();
|
||||
for v in v.iter() {
|
||||
let v = Value::from(v);
|
||||
x.push(v);
|
||||
}
|
||||
x.into()
|
||||
}
|
||||
_ => Value::Null,
|
||||
}
|
||||
}
|
||||
_ => Value::Null,
|
||||
}
|
||||
}
|
||||
}
|
93
lib/src/fnc/script/classes.rs
Normal file
93
lib/src/fnc/script/classes.rs
Normal file
|
@ -0,0 +1,93 @@
|
|||
#[js::bind(object, public)]
|
||||
#[quickjs(bare)]
|
||||
pub mod duration {
|
||||
|
||||
#[derive(Clone)]
|
||||
#[quickjs(class)]
|
||||
pub struct Duration {
|
||||
#[quickjs(hide)]
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
impl Duration {
|
||||
#[quickjs(constructor)]
|
||||
pub fn new(value: String) -> Self {
|
||||
Self {
|
||||
value,
|
||||
}
|
||||
}
|
||||
#[quickjs(rename = "toString")]
|
||||
pub fn output(&self) -> String {
|
||||
self.value.to_owned()
|
||||
}
|
||||
#[quickjs(get)]
|
||||
pub fn value(&self) -> &str {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[js::bind(object, public)]
|
||||
#[quickjs(bare)]
|
||||
pub mod uuid {
|
||||
|
||||
#[derive(Clone)]
|
||||
#[quickjs(class)]
|
||||
pub struct Uuid {
|
||||
#[quickjs(hide)]
|
||||
pub(crate) value: String,
|
||||
}
|
||||
|
||||
impl Uuid {
|
||||
#[quickjs(constructor)]
|
||||
pub fn new(value: String) -> Self {
|
||||
Self {
|
||||
value,
|
||||
}
|
||||
}
|
||||
#[quickjs(rename = "toString")]
|
||||
pub fn output(&self) -> String {
|
||||
self.value.to_owned()
|
||||
}
|
||||
#[quickjs(get)]
|
||||
pub fn value(&self) -> &str {
|
||||
&self.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[js::bind(object, public)]
|
||||
#[quickjs(bare)]
|
||||
pub mod record {
|
||||
|
||||
#[derive(Clone)]
|
||||
#[quickjs(class)]
|
||||
pub struct Record {
|
||||
#[quickjs(hide)]
|
||||
pub(crate) tb: String,
|
||||
#[quickjs(hide)]
|
||||
pub(crate) id: String,
|
||||
}
|
||||
|
||||
impl Record {
|
||||
#[quickjs(constructor)]
|
||||
pub fn new(tb: String, id: String) -> Self {
|
||||
Self {
|
||||
tb,
|
||||
id,
|
||||
}
|
||||
}
|
||||
#[quickjs(rename = "toString")]
|
||||
pub fn output(&self) -> String {
|
||||
format!("{}:{}", self.tb, self.id)
|
||||
}
|
||||
#[quickjs(get)]
|
||||
pub fn tb(&self) -> &str {
|
||||
&self.tb
|
||||
}
|
||||
#[quickjs(get)]
|
||||
pub fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
}
|
||||
}
|
19
lib/src/fnc/script/executor.rs
Normal file
19
lib/src/fnc/script/executor.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
use std::future::Future;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Executor<'a> {
|
||||
exe: executor::Executor<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Executor<'a> {
|
||||
pub async fn run<T>(&self, future: impl Future<Output = T>) -> T {
|
||||
self.exe.run(future).await
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> js::ExecutorSpawner for &Executor<'a> {
|
||||
type JoinHandle = executor::Task<()>;
|
||||
fn spawn_executor(self, task: js::Executor) -> Self::JoinHandle {
|
||||
self.exe.spawn(task)
|
||||
}
|
||||
}
|
92
lib/src/fnc/script/from.rs
Normal file
92
lib/src/fnc/script/from.rs
Normal file
|
@ -0,0 +1,92 @@
|
|||
use super::classes;
|
||||
use crate::sql::array::Array;
|
||||
use crate::sql::datetime::Datetime;
|
||||
use crate::sql::duration::Duration;
|
||||
use crate::sql::object::Object;
|
||||
use crate::sql::thing::Thing;
|
||||
use crate::sql::uuid::Uuid;
|
||||
use crate::sql::value::Value;
|
||||
use chrono::{TimeZone, Utc};
|
||||
use js::Ctx;
|
||||
use js::Error;
|
||||
use js::FromAtom;
|
||||
use js::FromJs;
|
||||
|
||||
impl<'js> FromJs<'js> for Value {
|
||||
fn from_js(ctx: Ctx<'js>, val: js::Value<'js>) -> Result<Self, Error> {
|
||||
match val {
|
||||
val if val.type_name() == "null" => Ok(Value::Null),
|
||||
val if val.type_name() == "undefined" => Ok(Value::None),
|
||||
val if val.is_bool() => Ok(val.as_bool().unwrap().into()),
|
||||
val if val.is_string() => match val.into_string().unwrap().to_string() {
|
||||
Ok(v) => Ok(Value::from(v)),
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
val if val.is_int() => Ok(val.as_int().unwrap().into()),
|
||||
val if val.is_float() => Ok(val.as_float().unwrap().into()),
|
||||
val if val.is_array() => {
|
||||
let v = val.as_array().unwrap();
|
||||
let mut x = Array::with_capacity(v.len());
|
||||
for i in v.iter() {
|
||||
let v = i?;
|
||||
let v = Value::from_js(ctx, v)?;
|
||||
x.push(v);
|
||||
}
|
||||
Ok(x.into())
|
||||
}
|
||||
val if val.is_object() => {
|
||||
// Extract the value as an object
|
||||
let v = val.into_object().unwrap();
|
||||
// Check to see if this object is a duration
|
||||
if (&v).instance_of::<classes::duration::Duration>() {
|
||||
let v = v.into_instance::<classes::duration::Duration>().unwrap();
|
||||
let v: &classes::duration::Duration = v.as_ref();
|
||||
let v = v.value.clone();
|
||||
return Ok(Duration::from(v).into());
|
||||
}
|
||||
// Check to see if this object is a record
|
||||
if (&v).instance_of::<classes::record::Record>() {
|
||||
let v = v.into_instance::<classes::record::Record>().unwrap();
|
||||
let v: &classes::record::Record = v.as_ref();
|
||||
let v = (v.tb.clone(), v.id.clone());
|
||||
return Ok(Thing::from(v).into());
|
||||
}
|
||||
// Check to see if this object is a uuid
|
||||
if (&v).instance_of::<classes::uuid::Uuid>() {
|
||||
let v = v.into_instance::<classes::uuid::Uuid>().unwrap();
|
||||
let v: &classes::uuid::Uuid = v.as_ref();
|
||||
let v = v.value.clone();
|
||||
return Ok(Uuid::from(v).into());
|
||||
}
|
||||
// Check to see if this object is a date
|
||||
let date: js::Object = ctx.globals().get("Date")?;
|
||||
if (&v).is_instance_of(&date) {
|
||||
let f: js::Function = v.get("getTime")?;
|
||||
let m: i64 = f.call((js::This(v),))?;
|
||||
let d = Utc.timestamp_millis(m);
|
||||
return Ok(Datetime::from(d).into());
|
||||
}
|
||||
// Check to see if this object is an array
|
||||
if let Some(v) = v.as_array() {
|
||||
let mut x = Array::with_capacity(v.len());
|
||||
for i in v.iter() {
|
||||
let v = i?;
|
||||
let v = Value::from_js(ctx, v)?;
|
||||
x.push(v);
|
||||
}
|
||||
return Ok(x.into());
|
||||
}
|
||||
// This object is a normal object
|
||||
let mut x = Object::default();
|
||||
for i in v.props() {
|
||||
let (k, v) = i?;
|
||||
let k = String::from_atom(k)?;
|
||||
let v = Value::from_js(ctx, v)?;
|
||||
x.insert(k, v);
|
||||
}
|
||||
Ok(x.into())
|
||||
}
|
||||
_ => Ok(Value::None),
|
||||
}
|
||||
}
|
||||
}
|
78
lib/src/fnc/script/into.rs
Normal file
78
lib/src/fnc/script/into.rs
Normal file
|
@ -0,0 +1,78 @@
|
|||
use super::classes;
|
||||
use crate::sql::number::Number;
|
||||
use crate::sql::value::Value;
|
||||
use bigdecimal::ToPrimitive;
|
||||
use js::Array;
|
||||
use js::Class;
|
||||
use js::Ctx;
|
||||
use js::Error;
|
||||
use js::IntoJs;
|
||||
use js::Null;
|
||||
use js::Object;
|
||||
use js::Undefined;
|
||||
|
||||
impl<'js> IntoJs<'js> for Value {
|
||||
fn into_js(self, ctx: Ctx<'js>) -> Result<js::Value<'js>, Error> {
|
||||
(&self).into_js(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'js> IntoJs<'js> for &Value {
|
||||
fn into_js(self, ctx: Ctx<'js>) -> Result<js::Value<'js>, Error> {
|
||||
match self {
|
||||
Value::Null => Null.into_js(ctx),
|
||||
Value::Void => Undefined.into_js(ctx),
|
||||
Value::None => Undefined.into_js(ctx),
|
||||
Value::True => Ok(js::Value::new_bool(ctx, true)),
|
||||
Value::False => Ok(js::Value::new_bool(ctx, false)),
|
||||
Value::Strand(v) => js::String::from_str(ctx, v)?.into_js(ctx),
|
||||
Value::Number(Number::Int(v)) => Ok(js::Value::new_int(ctx, *v as i32)),
|
||||
Value::Number(Number::Float(v)) => Ok(js::Value::new_float(ctx, *v as f64)),
|
||||
Value::Number(Number::Decimal(v)) => match v.is_integer() {
|
||||
true => Ok(js::Value::new_int(ctx, v.to_i32().unwrap_or_default())),
|
||||
false => Ok(js::Value::new_float(ctx, v.to_f64().unwrap_or_default())),
|
||||
},
|
||||
Value::Datetime(v) => {
|
||||
let date: js::Function = ctx.globals().get("Date")?;
|
||||
date.construct((v.0.timestamp_millis(),))
|
||||
}
|
||||
Value::Duration(v) => Ok(Class::<classes::duration::Duration>::instance(
|
||||
ctx,
|
||||
classes::duration::Duration {
|
||||
value: v.to_raw(),
|
||||
},
|
||||
)?
|
||||
.into_value()),
|
||||
Value::Thing(v) => Ok(Class::<classes::record::Record>::instance(
|
||||
ctx,
|
||||
classes::record::Record {
|
||||
tb: v.tb.to_owned(),
|
||||
id: v.id.to_raw(),
|
||||
},
|
||||
)?
|
||||
.into_value()),
|
||||
Value::Uuid(v) => Ok(Class::<classes::uuid::Uuid>::instance(
|
||||
ctx,
|
||||
classes::uuid::Uuid {
|
||||
value: v.to_raw(),
|
||||
},
|
||||
)?
|
||||
.into_value()),
|
||||
Value::Array(v) => {
|
||||
let x = Array::new(ctx)?;
|
||||
for (i, v) in v.iter().enumerate() {
|
||||
x.set(i, v)?;
|
||||
}
|
||||
x.into_js(ctx)
|
||||
}
|
||||
Value::Object(v) => {
|
||||
let x = Object::new(ctx)?;
|
||||
for (k, v) in v.iter() {
|
||||
x.set(k, v)?;
|
||||
}
|
||||
x.into_js(ctx)
|
||||
}
|
||||
_ => Undefined.into_js(ctx),
|
||||
}
|
||||
}
|
||||
}
|
65
lib/src/fnc/script/main.rs
Normal file
65
lib/src/fnc/script/main.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
use super::classes;
|
||||
use super::executor::Executor;
|
||||
use crate::ctx::Context;
|
||||
use crate::err::Error;
|
||||
use crate::sql::value::Value;
|
||||
use js::Promise;
|
||||
|
||||
pub async fn run(
|
||||
ctx: &Context<'_>,
|
||||
src: &str,
|
||||
arg: Vec<Value>,
|
||||
doc: Option<&Value>,
|
||||
) -> Result<Value, Error> {
|
||||
// Check the context
|
||||
let _ = ctx.check()?;
|
||||
// Create a new agent
|
||||
let exe = Executor::default();
|
||||
// Create an JavaScript context
|
||||
let run = js::Runtime::new().unwrap();
|
||||
// Create an execution context
|
||||
let ctx = js::Context::full(&run).unwrap();
|
||||
// Enable async code in the runtime
|
||||
run.spawn_executor(&exe).detach();
|
||||
// Convert the arguments to JavaScript
|
||||
let args = Value::from(arg);
|
||||
// Convert the current document to JavaScript
|
||||
let this = doc.map_or(&Value::None, |v| v);
|
||||
// Create the main function structure
|
||||
let src = format!("(async function() {{ {} }}).apply(self, args)", src);
|
||||
// Attempt to execute the script
|
||||
let res: Result<Promise<Value>, js::Error> = ctx.with(|ctx| {
|
||||
// Get the context global object
|
||||
let global = ctx.globals();
|
||||
// Register the Duration type as a global class
|
||||
global.init_def::<classes::Duration>().unwrap();
|
||||
// Register the Record type as a global class
|
||||
global.init_def::<classes::Record>().unwrap();
|
||||
// Register the Uuid type as a global class
|
||||
global.init_def::<classes::Uuid>().unwrap();
|
||||
// Register the document as a global object
|
||||
global.prop("self", this).unwrap();
|
||||
// Register the args as a global object
|
||||
global.prop("args", args).unwrap();
|
||||
// Attempt to execute the script
|
||||
ctx.eval(src)
|
||||
});
|
||||
// Return the script result
|
||||
let res = match res {
|
||||
// The script executed successfully
|
||||
Ok(v) => match exe.run(v).await {
|
||||
// The promise fulfilled successfully
|
||||
Ok(v) => Ok(v),
|
||||
// There was an error awaiting the promise
|
||||
Err(e) => Err(Error::InvalidScript {
|
||||
message: e.to_string(),
|
||||
}),
|
||||
},
|
||||
// There was an error running the script
|
||||
Err(e) => Err(Error::InvalidScript {
|
||||
message: e.to_string(),
|
||||
}),
|
||||
};
|
||||
// Return the result
|
||||
res
|
||||
}
|
9
lib/src/fnc/script/mod.rs
Normal file
9
lib/src/fnc/script/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
#![cfg(feature = "scripting")]
|
||||
|
||||
pub use main::run;
|
||||
|
||||
mod classes;
|
||||
mod executor;
|
||||
mod from;
|
||||
mod into;
|
||||
mod main;
|
|
@ -53,6 +53,12 @@ impl Deref for Duration {
|
|||
}
|
||||
}
|
||||
|
||||
impl Duration {
|
||||
pub fn to_raw(&self) -> String {
|
||||
self.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Duration {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// Split up the duration
|
||||
|
|
|
@ -49,6 +49,12 @@ impl Id {
|
|||
pub fn rand() -> Id {
|
||||
Id::String(nanoid!(20, &ID_CHARS))
|
||||
}
|
||||
pub fn to_raw(&self) -> String {
|
||||
match self {
|
||||
Id::Number(v) => v.to_string(),
|
||||
Id::String(v) => v.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Id {
|
||||
|
|
Loading…
Reference in a new issue