jansson_sys/
lib.rs

1#![allow(non_camel_case_types)]
2// See https://jansson.readthedocs.io/ for API documentation.
3
4use std::os::raw::{c_char, c_int, c_longlong, c_void};
5
6/// The type of a JSON value.
7#[repr(u32)]
8#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
9pub enum json_type {
10    JSON_OBJECT = 0,
11    JSON_ARRAY = 1,
12    JSON_STRING = 2,
13    JSON_INTEGER = 3,
14    JSON_REAL = 4,
15    JSON_TRUE = 5,
16    JSON_FALSE = 6,
17    JSON_NULL = 7,
18}
19
20/// The maximum possible indentation when pretty-printing JSON.
21pub const JSON_MAX_INDENT: u32 = 31;
22
23/// A JSON value.
24#[repr(C)]
25#[derive(Debug)]
26pub struct json_t {
27    pub type_: json_type,
28    pub refcount: usize,
29}
30
31/// An error that occurred during JSON processing.
32#[repr(C)]
33pub struct json_error_t {
34    pub line: c_int,
35    pub column: c_int,
36    pub position: c_int,
37    pub source: [c_char; 80usize],
38    pub text: [c_char; 160usize],
39}
40
41pub type json_load_callback_t = unsafe extern "C" fn(buffer: *mut c_void, buflen: usize, data: *mut c_void) -> usize;
42pub type json_dump_callback_t = unsafe extern "C" fn(buffer: *const c_char, size: usize, data: *mut c_void) -> c_int;
43pub type json_malloc_t = unsafe extern "C" fn(arg1: usize) -> *mut c_void;
44pub type json_free_t = unsafe extern "C" fn(arg1: *mut c_void);
45pub type json_int_t = c_longlong;
46
47extern "C" {
48    pub fn json_object() -> *mut json_t;
49    pub fn json_array() -> *mut json_t;
50    pub fn json_string(value: *const c_char) -> *mut json_t;
51    pub fn json_stringn(value: *const c_char, len: usize) -> *mut json_t;
52    pub fn json_string_nocheck(value: *const c_char) -> *mut json_t;
53    pub fn json_stringn_nocheck(value: *const c_char, len: usize) -> *mut json_t;
54    pub fn json_integer(value: json_int_t) -> *mut json_t;
55    pub fn json_real(value: f64) -> *mut json_t;
56    pub fn json_true() -> *mut json_t;
57    pub fn json_false() -> *mut json_t;
58    pub fn json_null() -> *mut json_t;
59    pub fn json_delete(json: *mut json_t);
60    pub fn json_object_seed(seed: usize);
61    pub fn json_object_size(object: *const json_t) -> usize;
62    pub fn json_object_get(object: *const json_t, key: *const c_char) -> *mut json_t;
63    pub fn json_object_set_new(object: *mut json_t, key: *const c_char, value: *mut json_t) -> c_int;
64    pub fn json_object_set_new_nocheck(object: *mut json_t, key: *const c_char, value: *mut json_t) -> c_int;
65    pub fn json_object_del(object: *mut json_t, key: *const c_char) -> c_int;
66    pub fn json_object_clear(object: *mut json_t) -> c_int;
67    pub fn json_object_update(object: *mut json_t, other: *mut json_t) -> c_int;
68    pub fn json_object_update_existing(object: *mut json_t, other: *mut json_t) -> c_int;
69    pub fn json_object_update_missing(object: *mut json_t, other: *mut json_t) -> c_int;
70    pub fn json_object_iter(object: *mut json_t) -> *mut c_void;
71    pub fn json_object_iter_at(object: *mut json_t, key: *const c_char) -> *mut c_void;
72    pub fn json_object_key_to_iter(key: *const c_char) -> *mut c_void;
73    pub fn json_object_iter_next(object: *mut json_t, iter: *mut c_void) -> *mut c_void;
74    pub fn json_object_iter_key(iter: *mut c_void) -> *const c_char;
75    pub fn json_object_iter_value(iter: *mut c_void) -> *mut json_t;
76    pub fn json_object_iter_set_new(object: *mut json_t, iter: *mut c_void, value: *mut json_t) -> c_int;
77    pub fn json_array_size(array: *const json_t) -> usize;
78    pub fn json_array_get(array: *const json_t, index: usize) -> *mut json_t;
79    pub fn json_array_set_new(array: *mut json_t, index: usize, value: *mut json_t) -> c_int;
80    pub fn json_array_append_new(array: *mut json_t, value: *mut json_t) -> c_int;
81    pub fn json_array_insert_new(array: *mut json_t, index: usize, value: *mut json_t) -> c_int;
82    pub fn json_array_remove(array: *mut json_t, index: usize) -> c_int;
83    pub fn json_array_clear(array: *mut json_t) -> c_int;
84    pub fn json_array_extend(array: *mut json_t, other: *mut json_t) -> c_int;
85    pub fn json_string_value(string: *const json_t) -> *const c_char;
86    pub fn json_string_length(string: *const json_t) -> usize;
87    pub fn json_integer_value(integer: *const json_t) -> json_int_t;
88    pub fn json_real_value(real: *const json_t) -> f64;
89    pub fn json_number_value(json: *const json_t) -> f64;
90    pub fn json_string_set(string: *mut json_t, value: *const c_char) -> c_int;
91    pub fn json_string_setn(string: *mut json_t, value: *const c_char, len: usize) -> c_int;
92    pub fn json_string_set_nocheck(string: *mut json_t, value: *const c_char) -> c_int;
93    pub fn json_string_setn_nocheck(string: *mut json_t, value: *const c_char, len: usize) -> c_int;
94    pub fn json_integer_set(integer: *mut json_t, value: json_int_t) -> c_int;
95    pub fn json_real_set(real: *mut json_t, value: f64) -> c_int;
96    pub fn json_pack(fmt: *const c_char, ...) -> *mut json_t;
97    pub fn json_pack_ex(error: *mut json_error_t, flags: usize, fmt: *const c_char, ...) -> *mut json_t;
98    pub fn json_unpack(root: *mut json_t, fmt: *const c_char, ...) -> c_int;
99    pub fn json_unpack_ex(root: *mut json_t, error: *mut json_error_t, flags: usize, fmt: *const c_char, ...) -> c_int;
100    pub fn json_equal(value1: *mut json_t, value2: *mut json_t) -> c_int;
101    pub fn json_copy(value: *mut json_t) -> *mut json_t;
102    pub fn json_deep_copy(value: *const json_t) -> *mut json_t;
103    pub fn json_loads(input: *const c_char, flags: usize, error: *mut json_error_t) -> *mut json_t;
104    pub fn json_loadb(buffer: *const c_char, buflen: usize, flags: usize, error: *mut json_error_t) -> *mut json_t;
105    pub fn json_loadfd(input: c_int, flags: usize, error: *mut json_error_t) -> *mut json_t;
106    pub fn json_load_file(path: *const c_char, flags: usize, error: *mut json_error_t) -> *mut json_t;
107    pub fn json_load_callback(callback: json_load_callback_t, data: *mut c_void, flags: usize, error: *mut json_error_t) -> *mut json_t;
108    pub fn json_dumps(json: *const json_t, flags: usize) -> *mut c_char;
109    pub fn json_dumpb(json: *const json_t, buffer: *mut c_char, size: usize, flags: usize) -> usize;
110    pub fn json_dumpfd(json: *const json_t, output: c_int, flags: usize) -> c_int;
111    pub fn json_dump_file(json: *const json_t, path: *const c_char, flags: usize) -> c_int;
112    pub fn json_dump_callback(json: *const json_t, callback: json_dump_callback_t, data: *mut c_void, flags: usize) -> c_int;
113    pub fn json_set_alloc_funcs(malloc_fn: json_malloc_t, free_fn: json_free_t);
114    pub fn json_get_alloc_funcs(malloc_fn: *mut json_malloc_t, free_fn: *mut json_free_t);
115}
116
117pub unsafe fn json_incref(json: *mut json_t) -> *mut json_t {
118    if !json.is_null() && (*json).refcount != usize::max_value() {
119        (*json).refcount += 1;
120    }
121    json
122}
123
124pub unsafe fn json_decref(json: *mut json_t) {
125    if !json.is_null() && (*json).refcount != usize::max_value() {
126        (*json).refcount -= 1;
127        if (*json).refcount == 0 {
128            json_delete(json);
129        }
130    }
131}
132
133#[cfg(test)]
134#[macro_use]
135extern crate cstr_macro;
136
137#[cfg(test)]
138mod tests {
139
140    use super::*;
141    use std::ffi::CStr;
142    use std::ptr;
143
144    #[test]
145    fn object_encoding() {
146        unsafe {
147            let x = json_object();
148            json_object_set_new(x, cstr!("a"), json_string(cstr!("alpha")));
149            json_object_set_new(x, cstr!("b"), json_true());
150            json_object_set_new(x, cstr!("c"), json_false());
151            json_object_set_new(x, cstr!("d"), json_integer(42));
152            json_object_set_new(x, cstr!("e"), json_real(1.25));
153            json_object_set_new(x, cstr!("f"), json_null());
154            let ys = json_array();
155            json_array_append_new(ys, json_integer(1));
156            json_array_append_new(ys, json_integer(3));
157            json_array_insert_new(ys, 1, json_integer(2));
158            json_object_set_new(x, cstr!("g"), ys);
159            let json = r#"{"a": "alpha", "b": true, "c": false, "d": 42, "e": 1.25, "f": null, "g": [1, 2, 3]}"#;
160            assert_eq!(json, CStr::from_ptr(json_dumps(x, 0)).to_str().unwrap());
161        }
162    }
163
164    #[test]
165    fn object_decoding() {
166        unsafe {
167            let json = cstr!(r#"{"a": {"aa": [true, false], "ab": null}, "b": {}, "c": "charlie", "d": 8.75}"#);
168            let root = json_loads(json, 0, ptr::null_mut());
169            assert!((*root).type_ == json_type::JSON_OBJECT);
170            let a = json_object_get(root, cstr!("a"));
171            assert!((*a).type_ == json_type::JSON_OBJECT);
172            let aa = json_object_get(a, cstr!("aa"));
173            assert!((*aa).type_ == json_type::JSON_ARRAY);
174            assert_eq!(json_array_size(aa), 2);
175            assert!((*json_array_get(aa, 0)).type_ == json_type::JSON_TRUE);
176            assert!((*json_array_get(aa, 1)).type_ == json_type::JSON_FALSE);
177            let ab = json_object_get(a, cstr!("ab"));
178            assert!((*ab).type_ == json_type::JSON_NULL);
179            let b = json_object_get(root, cstr!("b"));
180            assert!((*b).type_ == json_type::JSON_OBJECT);
181            assert_eq!(json_object_size(b), 0);
182            let c = json_object_get(root, cstr!("c"));
183            assert!((*c).type_ == json_type::JSON_STRING);
184            assert_eq!("charlie", CStr::from_ptr(json_string_value(c)).to_str().unwrap());
185            let d = json_object_get(root, cstr!("d"));
186            assert!((*d).type_ == json_type::JSON_REAL);
187            assert_eq!(8.75, json_real_value(d));
188        }
189    }
190}