1use libc::c_int;
2use std::ffi::{CStr, CString};
3use std::marker;
4use std::mem;
5
6use super::JsonnetVm;
7use jsonnet_sys::{self, JsonnetJsonValue};
8
9pub struct JsonVal<'a> {
13 vm: &'a JsonnetVm,
14 value: *const JsonnetJsonValue,
15}
16
17impl<'a> JsonVal<'a> {
18 pub unsafe fn from_ptr(vm: &'a JsonnetVm, p: *const JsonnetJsonValue) -> Self {
26 JsonVal { vm: vm, value: p }
27 }
28
29 pub fn as_ptr(&self) -> *const JsonnetJsonValue {
33 self.value
34 }
35
36 pub fn as_str(&self) -> Option<&str> {
38 unsafe {
39 let p = jsonnet_sys::jsonnet_json_extract_string(self.vm.as_ptr(), self.as_ptr());
40 if p.is_null() {
41 None
42 } else {
43 Some(CStr::from_ptr(p).to_str().unwrap())
45 }
46 }
47 }
48
49 pub fn as_num(&self) -> Option<f64> {
51 let mut number = 0.0;
52 let ok = unsafe {
53 jsonnet_sys::jsonnet_json_extract_number(self.vm.as_ptr(), self.as_ptr(), &mut number)
54 };
55 if ok != 0 {
56 Some(number)
57 } else {
58 None
59 }
60 }
61
62 pub fn as_bool(&self) -> Option<bool> {
64 let v = unsafe { jsonnet_sys::jsonnet_json_extract_bool(self.vm.as_ptr(), self.as_ptr()) };
65 match v {
66 0 => Some(false),
67 1 => Some(true),
68 2 => None,
69 _ => unreachable!(),
70 }
71 }
72
73 pub fn as_null(&self) -> Option<()> {
75 let v = unsafe { jsonnet_sys::jsonnet_json_extract_null(self.vm.as_ptr(), self.as_ptr()) };
76 match v {
77 0 => None,
78 1 => Some(()),
79 _ => unreachable!(),
80 }
81 }
82}
83
84pub struct JsonValue<'a> {
89 vm: &'a JsonnetVm,
90 value: *mut JsonnetJsonValue,
91 _marker: marker::PhantomData<JsonnetJsonValue>,
92}
93
94impl<'a> JsonValue<'a> {
95 pub unsafe fn from_ptr(vm: &'a JsonnetVm, p: *mut JsonnetJsonValue) -> Self {
103 JsonValue {
104 vm: vm,
105 value: p,
106 _marker: marker::PhantomData,
107 }
108 }
109
110 pub fn as_ptr(&self) -> *const JsonnetJsonValue {
114 self.value
115 }
116
117 pub fn as_str(&self) -> Option<&str> {
119 unsafe {
120 let p = jsonnet_sys::jsonnet_json_extract_string(self.vm.as_ptr(), self.as_ptr());
121 if p.is_null() {
122 None
123 } else {
124 Some(CStr::from_ptr(p).to_str().unwrap())
126 }
127 }
128 }
129
130 pub fn as_num(&self) -> Option<f64> {
132 let mut number = 0.0;
133 let ok = unsafe {
134 jsonnet_sys::jsonnet_json_extract_number(self.vm.as_ptr(), self.as_ptr(), &mut number)
135 };
136 if ok != 0 {
137 Some(number)
138 } else {
139 None
140 }
141 }
142
143 pub fn as_bool(&self) -> Option<bool> {
145 let v = unsafe { jsonnet_sys::jsonnet_json_extract_bool(self.vm.as_ptr(), self.as_ptr()) };
146 match v {
147 0 => Some(false),
148 1 => Some(true),
149 2 => None,
150 _ => unreachable!(),
151 }
152 }
153
154 pub fn as_null(&self) -> Option<()> {
156 let v = unsafe { jsonnet_sys::jsonnet_json_extract_null(self.vm.as_ptr(), self.as_ptr()) };
157 match v {
158 0 => None,
159 1 => Some(()),
160 _ => unreachable!(),
161 }
162 }
163
164 pub fn from_str(vm: &'a JsonnetVm, v: &str) -> Self {
170 let cstr = CString::new(v).unwrap();
171 unsafe {
172 let p = jsonnet_sys::jsonnet_json_make_string(vm.as_ptr(), cstr.as_ptr());
173 Self::from_ptr(vm, p)
174 }
175 }
176
177 pub fn from_num(vm: &'a JsonnetVm, v: f64) -> Self {
179 unsafe {
180 let p = jsonnet_sys::jsonnet_json_make_number(vm.as_ptr(), v);
181 Self::from_ptr(vm, p)
182 }
183 }
184
185 pub fn from_bool(vm: &'a JsonnetVm, v: bool) -> Self {
187 unsafe {
188 let p = jsonnet_sys::jsonnet_json_make_bool(vm.as_ptr(), v as c_int);
189 Self::from_ptr(vm, p)
190 }
191 }
192
193 pub fn null(vm: &'a JsonnetVm) -> Self {
195 unsafe {
196 let p = jsonnet_sys::jsonnet_json_make_null(vm.as_ptr());
197 Self::from_ptr(vm, p)
198 }
199 }
200
201 pub fn from_array<T>(vm: &'a JsonnetVm, iter: T) -> Self
203 where
204 T: IntoIterator<Item = JsonValue<'a>>,
205 {
206 unsafe {
207 let p = jsonnet_sys::jsonnet_json_make_array(vm.as_ptr());
208 for item in iter {
209 jsonnet_sys::jsonnet_json_array_append(vm.as_ptr(), p, item.into_raw());
210 }
211 Self::from_ptr(vm, p)
212 }
213 }
214
215 pub fn from_map<'b, T>(vm: &'a JsonnetVm, iter: T) -> Self
217 where
218 T: IntoIterator<Item = (&'b CStr, JsonValue<'a>)>,
219 {
220 unsafe {
221 let p = jsonnet_sys::jsonnet_json_make_object(vm.as_ptr());
222 for (f, v) in iter {
223 jsonnet_sys::jsonnet_json_object_append(vm.as_ptr(), p, f.as_ptr(), v.into_raw());
224 }
225 Self::from_ptr(vm, p)
226 }
227 }
228
229 pub fn into_raw(self) -> *mut JsonnetJsonValue {
236 let result = self.value;
237 mem::forget(self);
238 result
239 }
240}
241
242impl<'a> Drop for JsonValue<'a> {
243 fn drop(&mut self) {
244 unsafe {
245 jsonnet_sys::jsonnet_json_destroy(self.vm.as_ptr(), self.value);
246 }
247 }
248}