1use std::ffi::{CStr, CString};
7use std::os::raw::c_char;
8
9use crate::apply;
10use crate::gap::{Artifact, Envelope};
11
12#[no_mangle]
25pub unsafe extern "C" fn gap_resolve_envelope(
26 op_json: *const c_char,
27 art_json: *const c_char,
28) -> *mut c_char {
29 let op_str = match unsafe { CStr::from_ptr(op_json) }.to_str() {
30 Ok(s) => s,
31 Err(_) => return std::ptr::null_mut(),
32 };
33
34 let art_str = if art_json.is_null() {
35 None
36 } else {
37 match unsafe { CStr::from_ptr(art_json) }.to_str() {
38 Ok(s) => Some(s),
39 Err(_) => return std::ptr::null_mut(),
40 }
41 };
42
43 match resolve(op_str, art_str) {
44 Ok(s) => CString::new(s)
45 .map(|c| c.into_raw())
46 .unwrap_or(std::ptr::null_mut()),
47 Err(_) => std::ptr::null_mut(),
48 }
49}
50
51#[no_mangle]
56pub unsafe extern "C" fn gap_free_string(s: *mut c_char) {
57 if !s.is_null() {
58 drop(unsafe { CString::from_raw(s) });
59 }
60}
61
62fn resolve(op_json: &str, art_json: Option<&str>) -> anyhow::Result<String> {
63 let envelope: Envelope = serde_json::from_str(op_json)?;
64 let artifact = art_json
65 .map(serde_json::from_str::<Artifact>)
66 .transpose()?;
67 let (result_artifact, handle) = apply::apply(artifact.as_ref(), &envelope)?;
68 Ok(serde_json::to_string(&serde_json::json!({
69 "artifact": result_artifact,
70 "handle": handle,
71 }))?)
72}