reifydb_sdk/transform/
exports.rs1use std::{collections::HashMap, ffi::c_void, ptr, slice};
5
6use postcard::from_bytes;
7use reifydb_abi::{
8 constants::CURRENT_API,
9 data::buffer::BufferFFI,
10 transform::{descriptor::TransformDescriptorFFI, types::TRANSFORM_MAGIC},
11};
12use reifydb_type::value::Value;
13
14use crate::transform::{
15 FFITransformWithMetadata,
16 wrapper::{TransformWrapper, create_transform_vtable},
17};
18
19fn str_to_buffer(s: &'static str) -> BufferFFI {
20 BufferFFI {
21 ptr: s.as_ptr(),
22 len: s.len(),
23 cap: s.len(),
24 }
25}
26
27pub fn create_transform_descriptor<T: FFITransformWithMetadata>() -> TransformDescriptorFFI {
28 TransformDescriptorFFI {
29 api: CURRENT_API,
30 name: str_to_buffer(T::NAME),
31 version: str_to_buffer(T::VERSION),
32 description: str_to_buffer(T::DESCRIPTION),
33 vtable: create_transform_vtable::<T>(),
34 }
35}
36
37pub unsafe extern "C" fn create_transform_instance<T: FFITransformWithMetadata>(
41 config_ptr: *const u8,
42 config_len: usize,
43) -> *mut c_void {
44 let config = if config_ptr.is_null() || config_len == 0 {
45 HashMap::new()
46 } else {
47 let config_bytes = unsafe { slice::from_raw_parts(config_ptr, config_len) };
48
49 match from_bytes::<HashMap<String, Value>>(config_bytes) {
50 Ok(decoded_config) => decoded_config,
51 Err(e) => {
52 panic!("Failed to deserialize transform config: {}", e);
53 }
54 }
55 };
56
57 let transform = match T::new(&config) {
58 Ok(t) => t,
59 Err(e) => {
60 eprintln!("Failed to create transform: {}", e);
61 return ptr::null_mut();
62 }
63 };
64
65 let wrapper = Box::new(TransformWrapper::new(transform));
66 Box::into_raw(wrapper) as *mut c_void
67}
68
69pub extern "C" fn transform_magic() -> u32 {
70 TRANSFORM_MAGIC
71}