/* nanojson - very small JSON event parser with push API - semantic level

   This nanolib is written by Tibor 'Igor2' Palinkas in 2023 and 2024 and
   is licensed under the Creative Common CC0 (or is placed in the Public Domain
   where it is permitted by the law). */
#ifndef LIBNANOJSON_SEMANTIC_H
#define LIBNANOJSON_SEMANTIC_H

#include <libnanojson/nanojson.h>

typedef enum njson_sem_ev_e {
	/* if any of these is returned a new semantic construct has been read
	   succesfully and more characters shall be pushed */
	NJSON_SEM_EV_OBJECT_BEGIN,      /* BEGIN/END won't have type or value */
	NJSON_SEM_EV_OBJECT_END,
	NJSON_SEM_EV_ARRAY_BEGIN,
	NJSON_SEM_EV_ARRAY_END,

	NJSON_SEM_EV_ATOMIC,            /* name in ctx->name, type is ctx->type, ctx->value */

	NJSON_SEM_EV_error,             /* ran into an unrecoverable error - don't push more */
	NJSON_SEM_EV_eof,               /* reached eof - don't push more */
	NJSON_SEM_EV_more               /* token not complete, please push more */
} njson_sem_ev_t;

typedef enum njson_sem_type_e {
	NJSON_SEM_TYPE_STRING,            /* value in ctx->value.string */
	NJSON_SEM_TYPE_NUMBER,            /* value in ctx->value.number */
	NJSON_SEM_TYPE_TRUE,
	NJSON_SEM_TYPE_FALSE,
	NJSON_SEM_TYPE_NULL
} njson_sem_type_t;


typedef struct njson_sem_ctx_s {
	njson_ctx_t njs; /* use location info and error from this */

	njson_sem_type_t type;
	char *name;
	union {
		char *string;
		double number;
	} value;

	/* private/internal */
	unsigned reset_name:1;
} njson_sem_ctx_t;

/* Push the next character into the parser. chr is -1 for EOF. Return value
   indicates if a token completed and/or if more characters should be pushed.
   ctx should be all zero before the first call. */
njson_sem_ev_t njson_sem_push(njson_sem_ctx_t *ctx, int chr);

/* Free all memory of ctx and reset it to all-zero */
void njson_sem_uninit(njson_sem_ctx_t *ctx);
#endif
