1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
5
6extern "C" {
7 pub fn jsonnet_realloc(
9 vm: *mut JsonnetVm,
10 str_: *mut std::os::raw::c_char,
11 sz: size_t,
12 ) -> ::std::os::raw::c_int;
13}
14
15#[cfg(test)]
16mod tests {
17 #[test]
18 fn library_version() {
19 let cstr = unsafe { std::ffi::CStr::from_ptr(super::jsonnet_version()) };
20 assert_eq!(cstr.to_str().unwrap(), "v0.17.0 (go-jsonnet)");
21 }
22
23 #[test]
24 fn evaluate_snippet() {
25 let filename = std::ffi::CString::new("evaluate_snippet.jsonnet")
26 .unwrap()
27 .into_raw();
28 let code = std::ffi::CString::new("{foo: 1+2, bar: std.isBoolean(false)}")
29 .unwrap()
30 .into_raw();
31 let result = unsafe {
32 let vm = super::jsonnet_make();
33 let mut err = 0;
34 let result_ptr = super::jsonnet_evaluate_snippet(vm, filename, code, &mut err);
35 let result = std::ffi::CStr::from_ptr(result_ptr)
36 .to_string_lossy()
37 .into_owned();
38 super::jsonnet_realloc(vm, result_ptr, 0);
39 super::jsonnet_destroy(vm);
40 if err == 0 {
41 Ok(result)
42 } else {
43 Err(result)
44 }
45 };
46 assert!(result.is_ok());
47 #[derive(Debug, PartialEq, serde::Deserialize)]
48 struct S {
49 foo: i32,
50 bar: bool,
51 }
52 let s: S = serde_json::from_str(&result.unwrap()).unwrap();
53 assert_eq!(s, S { foo: 3, bar: true });
54 }
55
56 #[test]
57 fn evaluate_snippet_syntax_error() {
58 let filename = std::ffi::CString::new("evaluate_snippet.jsonnet")
59 .unwrap()
60 .into_raw();
61 let code = std::ffi::CString::new("{foo: 1+}").unwrap().into_raw();
62 let result = unsafe {
63 let vm = super::jsonnet_make();
64 let mut err = 0;
65 let result_ptr = super::jsonnet_evaluate_snippet(vm, filename, code, &mut err);
66 let result = std::ffi::CStr::from_ptr(result_ptr)
67 .to_string_lossy()
68 .into_owned();
69 super::jsonnet_realloc(vm, result_ptr, 0);
70 super::jsonnet_destroy(vm);
71 if err == 0 {
72 Ok(result)
73 } else {
74 Err(result)
75 }
76 };
77 assert!(result.is_err());
78 assert!(result
79 .unwrap_err()
80 .starts_with("evaluate_snippet.jsonnet:1:"));
81 }
82
83 #[test]
84 fn native_callback() {
85 let filename = std::ffi::CString::new("native_callback.jsonnet")
86 .unwrap()
87 .into_raw();
88 let code = std::ffi::CString::new(
89 r#"
90 local hello = std.native("hello");
91 { message: hello("world") }
92 "#,
93 )
94 .unwrap()
95 .into_raw();
96 let name = std::ffi::CString::new("hello").unwrap().into_raw();
97 unsafe extern "C" fn callback(
98 ctx: *mut std::ffi::c_void,
99 argv: *const *const super::JsonnetJsonValue,
100 success: *mut i32,
101 ) -> *mut super::JsonnetJsonValue {
102 let vm = ctx as *mut super::JsonnetVm;
103 let arg_c =
104 super::jsonnet_json_extract_string(vm, *argv as *mut super::JsonnetJsonValue);
105 let arg = std::ffi::CStr::from_ptr(arg_c).to_str().unwrap();
106 let s = super::jsonnet_json_make_string(
107 vm,
108 std::ffi::CString::new(format!("hello {}", arg))
109 .unwrap()
110 .into_raw(),
111 );
112 *success = 1;
113 s
114 }
115 let mut params = vec![
116 std::ffi::CString::new("s").unwrap().into_raw(),
117 std::ptr::null_mut(),
118 ];
119 let result = unsafe {
120 let vm = super::jsonnet_make();
121 super::jsonnet_native_callback(
122 vm,
123 name,
124 Some(callback),
125 vm as *mut std::ffi::c_void,
126 params.as_mut_ptr(),
127 );
128 let mut err = 0;
129 let result_ptr = super::jsonnet_evaluate_snippet(vm, filename, code, &mut err);
130 let result = std::ffi::CStr::from_ptr(result_ptr)
131 .to_string_lossy()
132 .into_owned();
133 super::jsonnet_realloc(vm, result_ptr, 0);
134 super::jsonnet_destroy(vm);
135 if err == 0 {
136 Ok(result)
137 } else {
138 Err(result)
139 }
140 };
141 assert!(result.is_ok());
142 #[derive(Debug, PartialEq, serde::Deserialize)]
143 struct S {
144 message: String,
145 }
146 let s: S = serde_json::from_str(&result.unwrap()).unwrap();
147 assert_eq!(
148 s,
149 S {
150 message: "hello world".to_owned()
151 }
152 );
153 }
154}