use deno_core::serde_json;
use rustyscript::{
worker::{InnerWorker, Worker},
Error, Runtime,
};
fn main() -> Result<(), Error> {
let worker = MyWorker::new(MyWorkerOptions {
timeout: std::time::Duration::from_secs(1),
})?;
let result: i32 = worker.execute("1 + 2")?;
assert_eq!(result, 3);
Ok(())
}
pub struct MyWorker(Worker<MyWorker>);
impl MyWorker {
pub fn new(options: MyWorkerOptions) -> Result<Self, Error> {
Ok(Self(Worker::new(options)?))
}
pub fn execute<T>(&self, code: &str) -> Result<T, Error>
where
T: serde::de::DeserializeOwned,
{
match self
.0
.send_and_await(MyWorkerMessage::Execute(code.to_string()))?
{
MyWorkerMessage::Value(v) => Ok(serde_json::from_value(v)?),
MyWorkerMessage::Error(e) => Err(e),
_ => Err(Error::Runtime("Unexpected response".to_string())),
}
}
}
pub enum MyWorkerMessage {
Execute(String),
Error(Error),
Value(serde_json::Value),
}
#[derive(Clone)]
pub struct MyWorkerOptions {
pub timeout: std::time::Duration,
}
impl InnerWorker for MyWorker {
type Query = MyWorkerMessage;
type Response = MyWorkerMessage;
type RuntimeOptions = MyWorkerOptions;
type Runtime = Runtime;
fn init_runtime(options: Self::RuntimeOptions) -> Result<Self::Runtime, Error> {
Runtime::new(rustyscript::RuntimeOptions {
timeout: options.timeout,
..Default::default()
})
}
fn handle_query(runtime: &mut Self::Runtime, query: Self::Query) -> Self::Response {
match query {
MyWorkerMessage::Execute(code) => match runtime.eval::<serde_json::Value>(&code) {
Ok(value) => MyWorkerMessage::Value(value),
Err(e) => MyWorkerMessage::Error(e),
},
MyWorkerMessage::Error(e) => MyWorkerMessage::Error(e),
MyWorkerMessage::Value(v) => MyWorkerMessage::Value(v),
}
}
}