use std::mem; use std::slice; use std::str; use cel::{Context, ExecutionError, Program, Value}; #[unsafe(no_mangle)] pub extern "C" fn allocation(n: usize) -> *mut u8 { mem::ManuallyDrop::new(Vec::with_capacity(n)).as_mut_ptr() } #[unsafe(no_mangle)] pub unsafe extern "C" fn evaluate(s: *const u8) -> *mut u8 { unsafe { let length = u32::from_le_bytes(*(s as *const [u8; 4])) as usize; let input = slice::from_raw_parts(s.offset(4), length); let output = evaluate_buffers(input); mem::ManuallyDrop::new(output).as_mut_ptr() } } fn evaluate_buffers(input: &[u8]) -> Vec { let contents = str::from_utf8(input).unwrap(); let result = evaluate_cel(contents); let success = result.is_ok(); let message = result.unwrap_or_else(|e| e.to_string()); let len = message.len(); let mut buffer = Vec::with_capacity(len + 8); buffer.push(if success { 1 } else { 0 }); buffer.extend(vec![0; 3]); buffer.extend_from_slice(&(len as u32).to_le_bytes()); buffer.extend_from_slice(message.as_bytes()); buffer } fn evaluate_cel(content: &str) -> Result { let program = Program::compile(content).unwrap(); let mut context = Context::default(); // context.add_function("add", |a: i64, b: i64| a + b); let value = program.execute(&context)?; Ok(format!("{:?}", value)) }