#ifndef CSONPATH_RUST_BACKEND_H_
#define CSONPATH_RUST_BACKEND_H_
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CSONPATH_JSON void *
#define CSONPATH_NULL NULL
extern void rust_decref(void *obj);
extern void *rust_new_object(void);
extern void *rust_new_array(void);
extern void rust_array_append(void *list, void *el);
extern void rust_array_append_incref(void *list, void *el);
extern void rust_array_clear(void *o);
extern void rust_obj_clear(void *o);
extern void *rust_get(void *obj, const char *key);
extern void *rust_at(void *arr, int idx);
extern size_t rust_array_length(void *arr);
extern int rust_is_obj(void *o);
extern int rust_is_array(void *o);
extern int rust_is_str(void *o);
extern int rust_is_num(void *o);
extern int rust_is_bool(void *o);
extern int rust_is_null(void *o);
extern const char *rust_get_str(void *o);
extern void rust_free_str(const char *s);
extern long long rust_get_num(void *o);
extern int rust_get_bool(void *o);
extern int rust_equal_num(void *o, long long v);
extern int rust_equal_str(void *o, const char *s);
extern void rust_remove_child(void *o, void *ci);
extern int rust_append_at_int(void *arr, int idx, void *el, int do_incref);
extern int rust_append_at_str(void *arr, const char *key, void *el, int do_incref);
extern int rust_need_foreach_redo(void *o);
extern int rust_call_callback(void *cb, void *ctx, void *ci, void *tmp, void *udata);
extern void rust_array_iter_init(void *it, void *arr);
extern int rust_array_iter_next(void *it, void **out_el, size_t *out_idx);
extern void rust_obj_iter_init(void *it, void *obj);
extern int rust_obj_iter_next(void *it, void **out_val,
const char **out_key, size_t *out_key_len);
extern void rust_obj_iter_free(void *it);
extern void rust_obj_iter_cleanup(void *it);
#define CSONPATH_GET(o, k) rust_get((o), (k))
#define CSONPATH_AT(o, i) rust_at((o), (i))
#define CSONPATH_ARRAY_LENGTH(o) ((size_t)rust_array_length(o))
#define CSONPATH_IS_OBJ(o) rust_is_obj(o)
#define CSONPATH_IS_ARRAY(o) rust_is_array(o)
#define CSONPATH_IS_STR(o) rust_is_str(o)
#define CSONPATH_IS_NUM(o) rust_is_num(o)
#define CSONPATH_IS_BOOL(o) rust_is_bool(o)
#define CSONPATH_IS_NULL(o) rust_is_null(o)
#define CSONPATH_GET_STR(o) rust_get_str(o)
#define CSONPATH_GET_NUM(o) rust_get_num(o)
#define CSONPATH_GET_BOOL(o) rust_get_bool(o)
#define CSONPATH_EQUAL_NUM(o, c) rust_equal_num((o), (c))
#define CSONPATH_EQUAL_STR(o, c) rust_equal_str((o), (c))
static inline void csonpath_cleanup_str(const char **p) {
if (*p) rust_free_str(*p);
}
#define CSONPATH_CLEANUP_STR __attribute__((cleanup(csonpath_cleanup_str)))
#define CSONPATH_REMOVE(o) rust_decref(o)
#define CSONPATH_NEW_OBJECT() rust_new_object()
#define CSONPATH_NEW_ARRAY() rust_new_array()
#define CSONPATH_ARRAY_APPEND(l, e) rust_array_append_incref((l), (e))
#define CSONPATH_ARRAY_CLEAR(o) rust_array_clear(o)
#define CSONPATH_OBJ_CLEAR(o) rust_obj_clear(o)
struct rust_array_iter {
void *arr;
size_t len;
size_t idx;
};
struct rust_obj_iter {
void *obj;
size_t len;
size_t idx;
void *entries;
};
#define _CSONPATH_ITER_CLEANUP(fn) __attribute__((cleanup(fn)))
#define CSONPATH_FOREACH_ARRAY(obj, child, idx) \
struct rust_array_iter _cpr_arr_it_; \
size_t _cpr_arr_idx_; \
rust_array_iter_init(&_cpr_arr_it_, (obj)); \
while (rust_array_iter_next(&_cpr_arr_it_, (void **)&(child), &_cpr_arr_idx_) && \
(((idx) = _cpr_arr_idx_), 1))
#define CSONPATH_FOREACH_OBJ(obj, child, key) \
struct rust_obj_iter _cpr_obj_it_ _CSONPATH_ITER_CLEANUP(rust_obj_iter_cleanup); \
size_t _cpr_key_len_; \
rust_obj_iter_init(&_cpr_obj_it_, (obj)); \
while (rust_obj_iter_next(&_cpr_obj_it_, (void **)&(child), &(key), &_cpr_key_len_))
#define CSONPATH_FOREACH_EXT(obj, el, code, key_idx_) \
if (rust_is_array(obj)) { \
struct rust_array_iter _cpr_ext_it_; \
rust_array_iter_init(&_cpr_ext_it_, (obj)); \
size_t key_idx_; \
void *el; \
while (rust_array_iter_next(&_cpr_ext_it_, (void **)&(el), &(key_idx_))) { \
code \
} \
} else if (rust_is_obj(obj)) { \
struct rust_obj_iter _cpr_ext_it_ _CSONPATH_ITER_CLEANUP(rust_obj_iter_cleanup); \
size_t _cpr_key_len2_; \
rust_obj_iter_init(&_cpr_ext_it_, (obj)); \
const char *key_idx_; \
void *el; \
while (rust_obj_iter_next(&_cpr_ext_it_, (void **)&(el), &(key_idx_), &_cpr_key_len2_)) { \
code \
} \
}
#define CSONPATH_REMOVE_CHILD(obj, child_info) \
rust_remove_child((obj), &(child_info))
#define CSONPATH_APPEND_AT(array, at, el, do_incref) \
_Generic((at), \
int: rust_append_at_int, \
unsigned int: rust_append_at_int, \
long: rust_append_at_int, \
unsigned long: rust_append_at_int, \
long long: rust_append_at_int, \
unsigned long long: rust_append_at_int, \
const char *: rust_append_at_str, \
char *: rust_append_at_str \
)((array), (at), (el), (do_incref))
#define CSONPATH_NEED_FOREACH_REDO(o) rust_need_foreach_redo(o)
#define CSONPATH_POST_CREATE_CTX(child_info, ctx, tmp) do { \
ctx = tmp = (child_info)->type == CSONPATH_INTEGER \
? CSONPATH_AT(ctx, (child_info)->idx) \
: CSONPATH_GET(ctx, (child_info)->key); \
if (ctx == CSONPATH_NULL) \
CSONPATH_EXCEPTION("Unable to re-fetch created node\n"); \
} while (0)
#define CSONPATH_CALLBACK void *
#define CSONPATH_CALLBACK_DATA void *
#define CSONPATH_CALL_CALLBACK(callback, ctx, child_info, tmp, udata) \
rust_call_callback((callback), (ctx), &(child_info), (tmp), (udata))
extern void rust_log_error(const char *msg);
#define CSONPATH_FORMAT_EXCEPTION(args...) do { \
char _cpr_err_buf[4096]; \
snprintf(_cpr_err_buf, sizeof(_cpr_err_buf), args); \
rust_log_error(_cpr_err_buf); \
} while (0)
#define CSONPATH_EXCEPTION(args...) do { \
CSONPATH_FORMAT_EXCEPTION(args); \
return -1; \
} while (0)
#include "csonpath.h"
#endif