datagen_rs/plugins/
plugin.rs1use crate::generate::current_schema::CurrentSchemaRef;
2use crate::generate::generated_schema::GeneratedSchema;
3use crate::util::types::Result;
4use serde_json::Value;
5use std::fmt::Debug;
6use std::sync::Arc;
7
8#[repr(C)]
9pub enum PluginInitResult {
10 Ok(*mut dyn Plugin),
11 Err(*mut std::ffi::c_char),
12}
13
14impl<T: Plugin + 'static> From<Result<T>> for PluginInitResult {
15 fn from(result: Result<T>) -> Self {
16 match result {
17 Ok(value) => PluginInitResult::Ok(Box::into_raw(Box::new(value))),
18 Err(err) => {
19 PluginInitResult::Err(std::ffi::CString::new(err.to_string()).unwrap().into_raw())
20 }
21 }
22 }
23}
24
25pub trait Plugin: Debug {
26 fn name(&self) -> String;
27
28 #[allow(unused_variables)]
29 fn generate(&self, schema: CurrentSchemaRef, args: Value) -> Result<Arc<GeneratedSchema>> {
30 Err("Operation 'generate' is not supported".into())
31 }
32
33 #[allow(unused_variables)]
34 fn transform(
35 &self,
36 schema: CurrentSchemaRef,
37 value: Arc<GeneratedSchema>,
38 args: Value,
39 ) -> Result<Arc<GeneratedSchema>> {
40 Err("Operation 'transform' is not supported".into())
41 }
42
43 #[allow(unused_variables)]
44 fn serialize(&self, value: &Arc<GeneratedSchema>, args: Value) -> Result<String> {
45 Err("Operation 'serialize' is not supported".into())
46 }
47}
48
49pub trait PluginConstructor: Plugin + Sized {
50 fn new(args: Value) -> Result<Self>;
51}
52
53#[macro_export]
54macro_rules! declare_plugin {
55 ($plugin_type:ty, $constructor: path) => {
56 impl PluginConstructor for $plugin_type {
57 fn new(args: Value) -> Result<Self> {
58 Ok($constructor())
59 }
60 }
61
62 declare_plugin!($plugin_type);
63 };
64 ($plugin_type:ty) => {
65 #[no_mangle]
66 pub unsafe extern "C" fn _plugin_create(
67 args: *mut Value,
68 ) -> datagen_rs::plugins::plugin::PluginInitResult {
69 let constructor: fn(args: Value) -> Result<$plugin_type> = <$plugin_type>::new;
71
72 let args = Box::from_raw(args);
73 constructor(*args).into()
74 }
75
76 #[no_mangle]
77 pub extern "C" fn _plugin_version() -> *mut std::ffi::c_char {
78 std::ffi::CString::new("1.0.0").unwrap().into_raw()
79 }
80 };
81}