use bumpalo::Bump;
use super::borrowed::Borrowed;
use super::build::{Build, Failure};
use super::owned::Owned;
use super::parser::Parser;
use crate::forms::text::{Doc, Spans, SyntaxError};
use crate::model::borrowed::ValueRef;
use crate::model::value::Value;
pub const MAX_DEPTH: usize = 256;
pub fn parse(text: &str) -> Result<Doc, SyntaxError> {
let (value, spans) = run::<Owned, true>(text, Owned::default())?;
Ok(Doc { value, spans })
}
pub fn parse_value(text: &str) -> Result<Value, SyntaxError> {
run::<Owned, false>(text, Owned::default()).map(|(v, _)| v)
}
pub fn parse_ref<'a>(text: &'a str, arena: &'a Bump) -> Result<ValueRef<'a>, SyntaxError> {
run::<Borrowed<'a>, false>(text, Borrowed::new(arena)).map(|(v, _)| v)
}
fn run<'t, B: Build<'t>, const SPANS: bool>(
text: &'t str,
builder: B,
) -> Result<(B::Value, Spans), SyntaxError> {
parse_all::<B, SPANS>(text, builder).map_err(Failure::into_inner)
}
fn parse_all<'t, B: Build<'t>, const SPANS: bool>(
text: &'t str,
builder: B,
) -> Result<(B::Value, Spans), Failure> {
let mut p = Parser::<B, SPANS>::new(text, builder);
if text.starts_with('\u{feff}') {
p.skip(3);
}
p.ws()?;
let mut root = Vec::new();
let value = p.value(None, &mut root)?;
p.ws()?;
if !p.at_end() {
return Err(p.error("unexpected text after the value"));
}
Ok((value, root.pop().unwrap_or_default()))
}