1use crate::*;
7use std::slice;
8
9unsafe fn read_bytes(ptr: *const u8, len: usize) -> Vec<u8> {
15 if ptr.is_null() || len == 0 {
16 return Vec::new();
17 }
18 slice::from_raw_parts(ptr, len).to_vec()
19}
20
21fn write_result(data: &[u8]) -> *mut u8 {
25 let total_len = 4 + data.len();
26 let mut buffer = Vec::with_capacity(total_len);
27
28 let len_bytes = (data.len() as u32).to_le_bytes();
30 buffer.extend_from_slice(&len_bytes);
31
32 buffer.extend_from_slice(data);
34
35 let ptr = buffer.as_mut_ptr();
37 std::mem::forget(buffer);
38 ptr
39}
40
41pub fn ffi_schema<F>(schema_fn: F) -> *mut u8
45where
46 F: Fn() -> String,
47{
48 let schema_content = schema_fn();
50
51 write_result(schema_content.as_bytes())
53}
54
55pub unsafe fn ffi_validate_config<F>(
60 level_ptr: *const u8,
61 level_len: usize,
62 config_ptr: *const u8,
63 config_len: usize,
64 validate_fn: F,
65) -> *mut u8
66where
67 F: Fn(ConfigLevel, JSON, &Utils) -> Vec<ValidationError>,
68{
69 let level_bytes = read_bytes(level_ptr, level_len);
71 let config_bytes = read_bytes(config_ptr, config_len);
72
73 let level: ConfigLevel = match serde_json::from_slice(&level_bytes) {
75 Ok(l) => l,
76 Err(e) => {
77 eprintln!("Failed to deserialize ConfigLevel: {}", e);
78 return write_result(b"[]");
79 }
80 };
81
82 let config: JSON = match serde_json::from_slice(&config_bytes) {
83 Ok(c) => c,
84 Err(e) => {
85 eprintln!("Failed to deserialize config: {}", e);
86 return write_result(b"[]");
87 }
88 };
89
90 let utils = Utils;
92 let errors = validate_fn(level, config, &utils);
93
94 let result_json = match serde_json::to_vec(&errors) {
96 Ok(json) => json,
97 Err(e) => {
98 eprintln!("Failed to serialize validation errors: {}", e);
99 return write_result(b"[]");
100 }
101 };
102
103 write_result(&result_json)
105}
106
107pub unsafe fn ffi_build<F>(
112 schema_ptr: *const u8,
113 schema_len: usize,
114 config_ptr: *const u8,
115 config_len: usize,
116 build_fn: F,
117) -> *mut u8
118where
119 F: Fn(Schema, JSON, &Utils) -> Vec<OutputFile>,
120{
121 let schema_bytes = read_bytes(schema_ptr, schema_len);
123 let config_bytes = read_bytes(config_ptr, config_len);
124
125 let schema: Schema = match serde_json::from_slice(&schema_bytes) {
127 Ok(s) => s,
128 Err(e) => {
129 eprintln!("Failed to deserialize Schema: {}", e);
130 return write_result(b"[]");
131 }
132 };
133
134 let config: JSON = match serde_json::from_slice(&config_bytes) {
135 Ok(c) => c,
136 Err(e) => {
137 eprintln!("Failed to deserialize config: {}", e);
138 return write_result(b"[]");
139 }
140 };
141
142 let utils = Utils;
144 let files = build_fn(schema, config, &utils);
145
146 let result_json = match serde_json::to_vec(&files) {
148 Ok(json) => json,
149 Err(e) => {
150 eprintln!("Failed to serialize output files: {}", e);
151 return write_result(b"[]");
152 }
153 };
154
155 write_result(&result_json)
157}
158
159pub unsafe fn ffi_migrate<F>(
164 schema_ptr: *const u8,
165 schema_len: usize,
166 deltas_ptr: *const u8,
167 deltas_len: usize,
168 config_ptr: *const u8,
169 config_len: usize,
170 migrate_fn: F,
171) -> *mut u8
172where
173 F: Fn(Schema, Vec<Delta>, JSON, &Utils) -> Vec<OutputFile>,
174{
175 let schema_bytes = read_bytes(schema_ptr, schema_len);
177 let deltas_bytes = read_bytes(deltas_ptr, deltas_len);
178 let config_bytes = read_bytes(config_ptr, config_len);
179
180 let schema: Schema = match serde_json::from_slice(&schema_bytes) {
182 Ok(s) => s,
183 Err(e) => {
184 eprintln!("Failed to deserialize Schema: {}", e);
185 return write_result(b"[]");
186 }
187 };
188
189 let deltas: Vec<Delta> = match serde_json::from_slice(&deltas_bytes) {
190 Ok(d) => d,
191 Err(e) => {
192 eprintln!("Failed to deserialize deltas: {}", e);
193 return write_result(b"[]");
194 }
195 };
196
197 let config: JSON = match serde_json::from_slice(&config_bytes) {
198 Ok(c) => c,
199 Err(e) => {
200 eprintln!("Failed to deserialize config: {}", e);
201 return write_result(b"[]");
202 }
203 };
204
205 let utils = Utils;
207 let files = migrate_fn(schema, deltas, config, &utils);
208
209 let result_json = match serde_json::to_vec(&files) {
211 Ok(json) => json,
212 Err(e) => {
213 eprintln!("Failed to serialize migration files: {}", e);
214 return write_result(b"[]");
215 }
216 };
217
218 write_result(&result_json)
220}
221
222#[no_mangle]
226pub extern "C" fn _alloc(size: usize) -> *mut u8 {
227 let mut buf = Vec::with_capacity(size);
228 let ptr = buf.as_mut_ptr();
229 std::mem::forget(buf);
230 ptr
231}
232
233#[no_mangle]
240pub unsafe extern "C" fn _dealloc(ptr: *mut u8, size: usize) {
241 if !ptr.is_null() && size > 0 {
242 let _ = Vec::from_raw_parts(ptr, 0, size);
243 }
244}
245
246#[macro_export]
248macro_rules! export_schema {
249 ($func:expr) => {
250 #[no_mangle]
251 pub extern "C" fn _schema() -> *mut u8 {
252 $crate::ffi::ffi_schema($func)
253 }
254 };
255}
256
257#[macro_export]
259macro_rules! export_validate_config {
260 ($func:expr) => {
261 #[no_mangle]
262 pub extern "C" fn _validate_config(
263 level_ptr: *const u8,
264 level_len: usize,
265 config_ptr: *const u8,
266 config_len: usize,
267 ) -> *mut u8 {
268 unsafe {
269 $crate::ffi::ffi_validate_config(
270 level_ptr,
271 level_len,
272 config_ptr,
273 config_len,
274 $func,
275 )
276 }
277 }
278 };
279}
280
281#[macro_export]
283macro_rules! export_build {
284 ($func:expr) => {
285 #[no_mangle]
286 pub extern "C" fn _build(
287 schema_ptr: *const u8,
288 schema_len: usize,
289 config_ptr: *const u8,
290 config_len: usize,
291 ) -> *mut u8 {
292 unsafe {
293 $crate::ffi::ffi_build(
294 schema_ptr,
295 schema_len,
296 config_ptr,
297 config_len,
298 $func,
299 )
300 }
301 }
302 };
303}
304
305#[macro_export]
307macro_rules! export_migrate {
308 ($func:expr) => {
309 #[no_mangle]
310 pub extern "C" fn _migrate(
311 schema_ptr: *const u8,
312 schema_len: usize,
313 deltas_ptr: *const u8,
314 deltas_len: usize,
315 config_ptr: *const u8,
316 config_len: usize,
317 ) -> *mut u8 {
318 unsafe {
319 $crate::ffi::ffi_migrate(
320 schema_ptr,
321 schema_len,
322 deltas_ptr,
323 deltas_len,
324 config_ptr,
325 config_len,
326 $func,
327 )
328 }
329 }
330 };
331}