power_play/src/json.h
2024-02-29 16:01:51 -06:00

144 lines
3.4 KiB
C

#ifndef JSON_H
#define JSON_H
enum json_type {
JSON_TYPE_INVALID,
JSON_TYPE_STRING,
JSON_TYPE_NULL,
JSON_TYPE_BOOL,
JSON_TYPE_ARRAY,
JSON_TYPE_OBJECT,
JSON_TYPE_NUMBER
};
struct json_object_entry;
struct json_ir_parent_data {
u32 child_count;
struct json_ir *child_first;
struct json_ir *child_last;
};
/* Intermediate representation of JSON hierarchy tree in memory. Used for mutating
* JSON in parsing stage or for creating new objects. Should be manipulated via the
* API. */
struct json_ir {
enum json_type type;
struct json_ir *next_child;
struct string key;
union {
struct json_ir_parent_data children;
b32 boolean;
struct string string;
f64 number;
} val;
};
/* Final representation of JSON hierarchy. Should be manipulated via the API. */
struct json_val {
enum json_type type;
u32 child_count;
union {
void *object_table;
struct json_val *array_children;
b32 boolean;
struct string *string;
f64 number;
} val;
};
struct json_object_entry {
struct string key;
struct json_val value;
};
/* Parse */
const struct json_ir *json_parse(struct arena *arena, struct buffer bytes, struct string **error);
/* Format */
const struct json_val *json_format(struct arena *arena, const struct json_ir *ir);
const struct json_val *json_parse_and_format(struct arena *arena, struct buffer bytes, struct string **error);
/* Index */
const struct json_val *json_array_get(const struct json_val *a, u32 index);
const struct json_val *json_object_get(const struct json_val *obj, struct string key);
const struct json_object_entry *json_object_get_index(const struct json_val *obj, u32 index);
/* Dump */
struct string json_dump_to_string(struct arena *arena, const struct json_val *val, u32 indent);
/* Write */
struct json_ir *json_ir_object(struct arena *arena);
struct json_ir *json_ir_number(struct arena *arena, f64 n);
struct json_ir *json_ir_bool(struct arena *arena, b32 b);
struct json_ir *json_ir_object_set(struct json_ir *obj, struct string key, struct json_ir *value);
/* ========================== *
* Type util
* ========================== */
INLINE b32 json_is_object(const struct json_val *v)
{
return v && v->type == JSON_TYPE_OBJECT;
}
INLINE b32 json_is_string(const struct json_val *v)
{
return v && v->type == JSON_TYPE_STRING;
}
INLINE b32 json_is_number(const struct json_val *v)
{
return v && v->type == JSON_TYPE_NUMBER;
}
INLINE b32 json_is_array(const struct json_val *v)
{
return v && v->type == JSON_TYPE_ARRAY;
}
INLINE b32 json_is_bool(const struct json_val *v)
{
return v && v->type == JSON_TYPE_BOOL;
}
INLINE b32 json_is_null(const struct json_val *v)
{
return v && v->type == JSON_TYPE_NULL;
}
/* ========================== *
* Val util
* ========================== */
INLINE struct string json_string(const struct json_val *v)
{
ASSERT(json_is_string(v));
return *v->val.string;
}
INLINE f64 json_number(const struct json_val *v)
{
ASSERT(json_is_number(v));
return v->val.number;
}
INLINE b32 json_bool(const struct json_val *v)
{
ASSERT(json_is_bool(v));
return v->val.boolean;
}
/* ========================== *
* Parent util
* ========================== */
INLINE u32 json_child_count(const struct json_val *v)
{
ASSERT(json_is_object(v) || json_is_array(v));
return v->child_count;
}
#endif