extern crate fidius_core as fidius;
use fidius_macro::{plugin_impl, plugin_interface};
#[plugin_interface(version = 1, buffer = Arena)]
pub trait EchoArena: Send + Sync {
fn echo(&self, input: String) -> String;
}
pub struct MyEcho;
#[plugin_impl(EchoArena, buffer = Arena)]
impl EchoArena for MyEcho {
fn echo(&self, input: String) -> String {
format!("echo: {input}")
}
}
fidius_core::fidius_plugin_registry!();
#[test]
fn arena_shim_round_trip_with_sufficient_buffer() {
let reg = fidius_core::registry::get_registry();
let desc = unsafe { &**reg.descriptors };
assert_eq!(desc.buffer_strategy, 2);
assert!(desc.free_buffer.is_none());
let vtable = unsafe { &*(desc.vtable as *const __fidius_EchoArena::EchoArena_VTable) };
let echo_fn = vtable.echo;
let input = ("hello".to_string(),);
let input_bytes = fidius_core::wire::serialize(&input).unwrap();
let mut arena = vec![0u8; 1024];
let mut out_offset: u32 = 0;
let mut out_len: u32 = 0;
let status = unsafe {
echo_fn(
input_bytes.as_ptr(),
input_bytes.len() as u32,
arena.as_mut_ptr(),
arena.len() as u32,
&mut out_offset,
&mut out_len,
)
};
assert_eq!(status, 0); assert_eq!(out_offset, 0);
assert!(out_len > 0);
let out_slice = &arena[out_offset as usize..(out_offset + out_len) as usize];
let result: String = fidius_core::wire::deserialize(out_slice).unwrap();
assert_eq!(result, "echo: hello");
}
#[test]
fn arena_shim_returns_buffer_too_small() {
let reg = fidius_core::registry::get_registry();
let desc = unsafe { &**reg.descriptors };
let vtable = unsafe { &*(desc.vtable as *const __fidius_EchoArena::EchoArena_VTable) };
let echo_fn = vtable.echo;
let input = ("this is a reasonably long payload".to_string(),);
let input_bytes = fidius_core::wire::serialize(&input).unwrap();
let mut arena = [0u8; 4];
let mut out_offset: u32 = 0;
let mut out_len: u32 = 0;
let status = unsafe {
echo_fn(
input_bytes.as_ptr(),
input_bytes.len() as u32,
arena.as_mut_ptr(),
arena.len() as u32,
&mut out_offset,
&mut out_len,
)
};
assert_eq!(status, -1);
assert!(out_len as usize > arena.len());
}