use crate::common::{number, string, whitespaces};
use std::sync::LazyLock;
use whitehole::{
action::Action,
combinator::{eat, recur, wrap, Combinator},
};
fn wso() -> Combinator<impl Action<Text = str, State = (), Heap = (), Value = ()>> {
whitespaces().optional()
}
fn sep() -> Combinator<impl Action<Text = str, State = (), Heap = (), Value = ()>> {
eat(',') + wso()
}
pub fn parser_entry_with_recur(
) -> Combinator<impl Action<Text = str, State = (), Heap = (), Value = ()>> {
let (value, value_setter) = recur();
let array = || eat('[') + wso() + ((value() + wso()) * (..)).sep(sep()) + ']';
let object = || {
let object_item = string() + wso() + eat(':') + wso() + value();
eat('{') + wso() + ((object_item + wso()) * (..)).sep(sep()) + '}'
};
value_setter.boxed(array() | object() | number() | string() | "true" | "false" | "null");
whitespaces() | value()
}
pub fn parser_entry_with_static(
) -> Combinator<impl Action<Text = str, State = (), Heap = (), Value = ()>> {
fn array() -> Combinator<impl Action<Text = str, State = (), Heap = (), Value = ()>> {
eat('[') + wso() + ((value() + wso()) * (..)).sep(sep()) + ']'
}
fn object() -> Combinator<impl Action<Text = str, State = (), Heap = (), Value = ()>> {
let object_item = string() + wso() + eat(':') + wso() + value();
eat('{') + wso() + ((object_item + wso()) * (..)).sep(sep()) + '}'
}
fn value() -> Combinator<impl Action<Text = str, State = (), Heap = (), Value = ()>> {
static VALUE: LazyLock<
Box<dyn Action<Text = str, State = (), Heap = (), Value = ()> + Send + Sync>,
> = LazyLock::new(|| {
Box::new(array() | object() | number() | string() | "true" | "false" | "null")
});
wrap(|input| VALUE.exec(input))
}
whitespaces() | value()
}