use super::types::{FFIResult, JSONEvalHandle};
use std::ffi::CStr;
use std::os::raw::c_char;
#[no_mangle]
pub unsafe extern "C" fn json_eval_evaluate_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
data: *const c_char,
context: *const c_char,
paths_json: *const c_char,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() || data.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let handle_ref = &mut *handle;
let token = handle_ref.reset_token();
let eval = &mut handle_ref.inner;
let path_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let data_str = match CStr::from_ptr(data).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in data".to_string()),
};
let context_str = if !context.is_null() {
match CStr::from_ptr(context).to_str() {
Ok(s) => Some(s),
Err(_) => return FFIResult::error("Invalid UTF-8 in context".to_string()),
}
} else {
None
};
let paths: Option<Vec<String>> = if !paths_json.is_null() {
match CStr::from_ptr(paths_json).to_str() {
Ok(s) => match serde_json::from_str(s) {
Ok(p) => Some(p),
Err(e) => return FFIResult::error(format!("Failed to parse paths JSON: {}", e)),
},
Err(_) => return FFIResult::error("Invalid UTF-8 in paths_json".to_string()),
}
} else {
None
};
match eval.evaluate_subform(
path_str,
data_str,
context_str,
paths.as_deref(),
token.as_ref(),
) {
Ok(_) => FFIResult::success(Vec::new()),
Err(e) => FFIResult::error(e),
}
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_validate_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
data: *const c_char,
context: *const c_char,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() || data.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let handle_ref = &mut *handle;
let token = handle_ref.reset_token();
let eval = &mut handle_ref.inner;
let path_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let data_str = match CStr::from_ptr(data).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in data".to_string()),
};
let context_str = if !context.is_null() {
match CStr::from_ptr(context).to_str() {
Ok(s) => Some(s),
Err(_) => return FFIResult::error("Invalid UTF-8 in context".to_string()),
}
} else {
None
};
match eval.validate_subform(path_str, data_str, context_str, None, token.as_ref()) {
Ok(validation_result) => {
let mut errors_map = serde_json::Map::new();
for (path, err) in &validation_result.errors {
errors_map.insert(
path.clone(),
serde_json::json!({
"path": path,
"type": err.rule_type,
"message": err.message,
"code": err.code,
"pattern": err.pattern,
"fieldValue": err.field_value,
"data": err.data,
}),
);
}
let result_json = serde_json::json!({
"hasError": validation_result.has_error,
"error": errors_map
});
let result_bytes = serde_json::to_vec(&result_json).unwrap_or_default();
FFIResult::success(result_bytes)
}
Err(e) => FFIResult::error(e),
}
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_evaluate_dependents_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
changed_path: *const c_char,
data: *const c_char,
context: *const c_char,
re_evaluate: i32,
include_subforms: i32,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() || changed_path.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let handle_ref = &mut *handle;
let token = handle_ref.reset_token();
let eval = &mut handle_ref.inner;
let subform_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let path_str = match CStr::from_ptr(changed_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in changed_path".to_string()),
};
let data_str = if !data.is_null() {
match CStr::from_ptr(data).to_str() {
Ok(s) => Some(s),
Err(_) => return FFIResult::error("Invalid UTF-8 in data".to_string()),
}
} else {
None
};
let context_str = if !context.is_null() {
match CStr::from_ptr(context).to_str() {
Ok(s) => Some(s),
Err(_) => return FFIResult::error("Invalid UTF-8 in context".to_string()),
}
} else {
None
};
let paths = vec![path_str.to_string()];
match eval.evaluate_dependents_subform(
subform_str,
&paths,
data_str,
context_str,
re_evaluate != 0,
token.as_ref(),
None,
include_subforms != 0,
) {
Ok(result) => {
let result_bytes = serde_json::to_vec(&result).unwrap_or_default();
FFIResult::success(result_bytes)
}
Err(e) => FFIResult::error(e),
}
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_resolve_layout_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
evaluate: bool,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let eval = &mut (*handle).inner;
let path_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
match eval.resolve_layout_subform(path_str, evaluate) {
Ok(_) => FFIResult::success(Vec::new()),
Err(e) => FFIResult::error(e),
}
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_get_evaluated_schema_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
resolve_layout: bool,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let eval = &mut (*handle).inner;
let path_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let result = eval.get_evaluated_schema_subform(path_str, resolve_layout);
let result_bytes = serde_json::to_vec(&result).unwrap_or_default();
FFIResult::success(result_bytes)
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_get_schema_value_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let eval = &mut (*handle).inner;
let path_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let result = eval.get_schema_value_subform(path_str);
let result_bytes = serde_json::to_vec(&result).unwrap_or_default();
FFIResult::success(result_bytes)
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_get_schema_value_array_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let eval = &mut (*handle).inner;
let path_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let result = eval.get_schema_value_array_subform(path_str);
let result_bytes = serde_json::to_vec(&result).unwrap_or_default();
FFIResult::success(result_bytes)
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_get_schema_value_object_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let eval = &mut (*handle).inner;
let path_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let result = eval.get_schema_value_object_subform(path_str);
let result_bytes = serde_json::to_vec(&result).unwrap_or_default();
FFIResult::success(result_bytes)
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_get_evaluated_schema_without_params_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
resolve_layout: bool,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let eval = &mut (*handle).inner;
let path_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let result = eval.get_evaluated_schema_without_params_subform(path_str, resolve_layout);
let result_bytes = serde_json::to_vec(&result).unwrap_or_default();
FFIResult::success(result_bytes)
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_get_evaluated_schema_by_path_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
schema_path: *const c_char,
skip_layout: bool,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() || schema_path.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let eval = &mut (*handle).inner;
let subform_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let path_str = match CStr::from_ptr(schema_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in schema_path".to_string()),
};
match eval.get_evaluated_schema_by_path_subform(subform_str, path_str, skip_layout) {
Some(value) => {
let result_bytes = serde_json::to_vec(&value).unwrap_or_default();
FFIResult::success(result_bytes)
}
None => FFIResult::error("Path not found in subform".to_string()),
}
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_get_evaluated_schema_by_paths_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
schema_paths_json: *const c_char,
skip_layout: bool,
format: u8,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() || schema_paths_json.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let eval = &mut (*handle).inner;
let subform_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let paths_str = match CStr::from_ptr(schema_paths_json).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in schema_paths".to_string()),
};
let paths: Vec<String> = match serde_json::from_str(paths_str) {
Ok(p) => p,
Err(e) => return FFIResult::error(format!("Failed to parse paths JSON: {}", e)),
};
let return_format = match format {
1 => crate::ReturnFormat::Flat,
2 => crate::ReturnFormat::Array,
_ => crate::ReturnFormat::Nested,
};
let result = eval.get_evaluated_schema_by_paths_subform(
subform_str,
&paths,
skip_layout,
Some(return_format),
);
let result_bytes = serde_json::to_vec(&result).unwrap_or_default();
FFIResult::success(result_bytes)
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_get_schema_by_path_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
schema_path: *const c_char,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() || schema_path.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let eval = &(*handle).inner;
let subform_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let path_str = match CStr::from_ptr(schema_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in schema_path".to_string()),
};
match eval.get_schema_by_path_subform(subform_str, path_str) {
Some(value) => {
let result_bytes = serde_json::to_vec(&value).unwrap_or_default();
FFIResult::success(result_bytes)
}
None => FFIResult::error("Path not found in subform".to_string()),
}
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_get_schema_by_paths_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
schema_paths_json: *const c_char,
format: u8,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() || schema_paths_json.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let eval = &(*handle).inner;
let subform_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let paths_str = match CStr::from_ptr(schema_paths_json).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in schema_paths".to_string()),
};
let paths: Vec<String> = match serde_json::from_str(paths_str) {
Ok(p) => p,
Err(e) => return FFIResult::error(format!("Failed to parse paths JSON: {}", e)),
};
let return_format = match format {
1 => crate::ReturnFormat::Flat,
2 => crate::ReturnFormat::Array,
_ => crate::ReturnFormat::Nested,
};
let result = eval.get_schema_by_paths_subform(subform_str, &paths, Some(return_format));
let result_bytes = serde_json::to_vec(&result).unwrap_or_default();
FFIResult::success(result_bytes)
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_get_subform_paths(handle: *mut JSONEvalHandle) -> FFIResult {
if handle.is_null() {
return FFIResult::error("Invalid handle pointer".to_string());
}
let eval = &(*handle).inner;
let paths = eval.get_subform_paths();
let result_bytes = serde_json::to_vec(&paths).unwrap_or_default();
FFIResult::success(result_bytes)
}
#[no_mangle]
pub unsafe extern "C" fn json_eval_has_subform(
handle: *mut JSONEvalHandle,
subform_path: *const c_char,
) -> FFIResult {
if handle.is_null() || subform_path.is_null() {
return FFIResult::error("Invalid pointer".to_string());
}
let eval = &(*handle).inner;
let path_str = match CStr::from_ptr(subform_path).to_str() {
Ok(s) => s,
Err(_) => return FFIResult::error("Invalid UTF-8 in subform_path".to_string()),
};
let has_subform = eval.has_subform(path_str);
let result = if has_subform { "true" } else { "false" };
let result_bytes = result.as_bytes().to_vec();
FFIResult::success(result_bytes)
}