Skip to content

Commit

Permalink
a few fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
rscarson committed Oct 23, 2023
1 parent ec9396e commit 8b2a10d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/extensions/mod.rs
Expand Up @@ -5,4 +5,5 @@ mod table;

pub use extension::Extension;
pub use function::ExtensionFunction;
pub use runtime::ExtensionsRuntime;
pub use table::ExtensionTable;
20 changes: 20 additions & 0 deletions src/extensions/runtime.rs
Expand Up @@ -57,6 +57,26 @@ impl ExtensionsRuntime {
self.0.load_module(module)
}

pub fn evaluate<T>(&mut self, expression: &str) -> Result<T, rustyscript::Error>
where
T: serde::de::DeserializeOwned,
{
let module = Module::new(
"js_eval.js",
&format!(
"
export function rustyscript_evaluate(){{
return ({expression});
}}
"
),
);

let module = self.0.load_modules(&module, vec![])?;
self.0
.call_function(&module, "rustyscript_evaluate", Runtime::EMPTY_ARGS)
}

pub fn call_function<T>(
&mut self,
context: &ModuleHandle,
Expand Down
22 changes: 21 additions & 1 deletion src/functions/builtins/system.rs
@@ -1,7 +1,27 @@
//! Builtin functions for lower level ops

use super::*;
use crate::{help::Help, ExpectedTypes, Token};
use crate::{define_function, extensions::ExtensionsRuntime, help::Help, ExpectedTypes, Token};

#[cfg(feature = "extensions")]
define_function!(
name = js,
description = "Run a javascript expression, and return the result",
arguments = [function_arg!("expression")],
handler = |function, token, state, args| {
ExtensionsRuntime::with(|runtime| {
let expression = args.get("input").required().as_string();
match runtime.evaluate::<serde_json::Value>(&expression) {
Ok(v) => Ok(Value::from_json(v).ok_or(Error::ValueParsing {
input: expression,
expected_type: ExpectedTypes::Any,
token: token.clone(),
})),
Err(e) => Err(Error::Javascript(e, token.clone())),
}
})?
}
);

const HELP: FunctionDefinition = FunctionDefinition {
name: "help",
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Expand Up @@ -391,6 +391,7 @@
#![doc(html_root_url = "https://docs.rs/lavendeux-parser/0.9.0")]
#![warn(missing_docs)]

#[cfg(feature = "extensions")]
pub use rustyscript;

mod errors;
Expand Down
19 changes: 19 additions & 0 deletions src/value.rs
Expand Up @@ -326,6 +326,25 @@ impl Value {
pub fn is_none(&self) -> bool {
matches!(self, Value::None)
}

// Attempt to convert the value from JSON
pub fn from_json(value: serde_json::Value) -> Option<Self> {
if let Ok(v) = serde_json::from_value::<FloatType>(value) {
Some(v.into())
} else if let Ok(v) = serde_json::from_value::<IntegerType>(value) {
Some(v.into())
} else if let Ok(v) = serde_json::from_value::<bool>(value) {
Some(v.into())
} else if let Ok(v) = serde_json::from_value::<&str>(value) {
Some(v.into())
} else if let Ok(v) = serde_json::from_value::<ArrayType>(value) {
Some(v.into())
} else if let Ok(v) = serde_json::from_value::<ObjectType>(value) {
Some(v.into())
} else {
None
}
}
}

impl Clone for Value {
Expand Down

0 comments on commit 8b2a10d

Please sign in to comment.