101 lines
2.4 KiB
Rust
101 lines
2.4 KiB
Rust
use crate::dataframe;
|
|
|
|
#[derive(Debug)]
|
|
pub struct Engine {
|
|
pub blocks: Vec<Block>,
|
|
engine: rhai::Engine,
|
|
}
|
|
|
|
impl Default for Engine {
|
|
fn default() -> Self {
|
|
let mut engine = rhai::Engine::new();
|
|
engine.set_fast_operators(false);
|
|
dataframe::setup_engine(&mut engine);
|
|
|
|
Self {
|
|
engine,
|
|
blocks: vec![Block::default()],
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Engine {
|
|
pub fn process(&mut self) {
|
|
for block in self.blocks.iter_mut() {
|
|
match self.engine.eval::<rhai::Dynamic>(&block.script) {
|
|
Ok(res) if res.is::<dataframe::DataFrame>() => {
|
|
let frame = rhai::Dynamic::cast::<dataframe::DataFrame>(res);
|
|
block.output = Output::DataFrame(frame);
|
|
}
|
|
Ok(res) if res.is::<dataframe::Series>() => {
|
|
let frame = rhai::Dynamic::cast::<dataframe::Series>(res);
|
|
block.output = Output::Series(frame);
|
|
}
|
|
Ok(res) => {
|
|
block.output = Output::Scalar(res);
|
|
}
|
|
Err(e) => {
|
|
block.output = Output::Error(e.to_string());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum Output {
|
|
None,
|
|
Scalar(rhai::Dynamic),
|
|
DataFrame(dataframe::DataFrame),
|
|
Series(dataframe::Series),
|
|
Error(String),
|
|
}
|
|
|
|
impl Output {
|
|
pub fn into_frame(self) -> dataframe::DataFrame {
|
|
if let Self::DataFrame(v) = self {
|
|
return v;
|
|
}
|
|
panic!("Not a dataframe");
|
|
}
|
|
pub fn into_series(self) -> dataframe::Series {
|
|
if let Self::Series(v) = self {
|
|
return v;
|
|
}
|
|
panic!("Not a series");
|
|
}
|
|
pub fn into_scalar(self) -> rhai::Dynamic {
|
|
if let Self::Scalar(v) = self {
|
|
return v;
|
|
}
|
|
panic!("Not a scalar");
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Block {
|
|
pub script: String,
|
|
pub output: Output,
|
|
}
|
|
|
|
impl Default for Block {
|
|
fn default() -> Self {
|
|
Self {
|
|
script: Default::default(),
|
|
output: Output::None,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub mod tests {
|
|
use super::*;
|
|
|
|
pub fn process(script: &str) -> Output {
|
|
let mut engine = Engine::default();
|
|
engine.blocks[0].script = script.into();
|
|
engine.process();
|
|
engine.blocks[0].output.clone()
|
|
}
|
|
}
|