use crate::errors::{Error, Result};
use crate::registry::Registry; use crate::script::{AggrType, Return, Script};
use crate::{registry, EventContext};
use simd_json::{prelude::*, BorrowedValue as Value};
use std::ffi::CStr;
use std::os::raw::c_char;
use std::ptr;
#[cfg_attr(tarpaulin, skip)]
fn eval(src: &str) -> Result<String> {
let reg: Registry = registry::registry();
let script = Script::parse(&crate::path::load(), "<eval>", src.to_string(), ®)
.map_err(|e| e.error)?;
let mut event = Value::object();
let mut meta = Value::object();
let mut state = Value::null();
let value = script.run(
&EventContext::new(0, None),
AggrType::Emit,
&mut event,
&mut state,
&mut meta,
)?;
Ok(match value {
Return::Drop => String::from(r#"{"drop": null}"#),
Return::Emit { value, .. } => format!(r#"{{"emit": {}}}"#, value.encode()),
Return::EmitEvent { .. } => format!(r#"{{"emit": {}}}"#, event.encode()),
})
}
#[no_mangle]
#[cfg_attr(tarpaulin, skip)]
pub extern "C" fn tremor_script_c_eval(script: *const c_char, dst: *mut u8, len: usize) -> usize {
let cstr = unsafe { CStr::from_ptr(script) };
match cstr
.to_str()
.map_err(Error::from)
.and_then(|ref mut s| eval(s))
{
Ok(result) => {
if result.len() < len {
unsafe {
let src = result.as_ptr() as *const u8;
ptr::copy_nonoverlapping(src, dst, result.len());
*dst.add(result.len()) = 0;
0
}
} else {
result.len()
}
}
Err(e) => {
eprintln!("ERROR: {}", e);
1
}
}
}