#![allow(dead_code)]
#![allow(clippy::result_large_err)]
use std::path::{Path, PathBuf};
use tabnas::{Tabnas, Value};
use tabnas_expr::{ExprOptions, OpDef, PrevalDef};
use tabnas_support::Failure;
pub fn repo_root() -> &'static Path {
Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("rs/ has a parent")
}
pub fn spec_dir() -> PathBuf {
repo_root().join("test").join("spec")
}
pub fn parser_for(options: serde_json::Value) -> Tabnas {
let mut parser = tabnas_jsonic::make();
parser
.use_plugin(tabnas_expr::plugin(), Some(Value::from_json(&options)))
.unwrap_or_else(|error| panic!("expr plugin: {error}"));
parser
}
pub fn parser_default() -> Tabnas {
parser_for(serde_json::json!({}))
}
pub fn parser_with(options: ExprOptions) -> Tabnas {
tabnas_expr::make_with(options)
}
pub fn to_failure(error: tabnas::TabnasError) -> Failure {
Failure::new(error.code.clone())
.at(error.row, error.col)
.with_message(error.to_string())
}
pub fn parse_simplified(
parser: &Tabnas,
src: &str,
) -> Result<serde_json::Value, tabnas::TabnasError> {
tabnas_expr::parse_simplified(parser, src).map(|value| value.to_json())
}
pub fn norm(value: serde_json::Value) -> serde_json::Value {
match value {
serde_json::Value::Number(number) => {
serde_json::Number::from_f64(number.as_f64().expect("a JSON number is representable"))
.map_or(serde_json::Value::Null, serde_json::Value::Number)
}
serde_json::Value::Array(entries) => {
serde_json::Value::Array(entries.into_iter().map(norm).collect())
}
serde_json::Value::Object(entries) => serde_json::Value::Object(
entries
.into_iter()
.map(|(key, entry)| (key, norm(entry)))
.collect(),
),
other => other,
}
}
pub fn preval(active: bool, required: bool, allow: Option<Vec<String>>) -> PrevalDef {
PrevalDef {
active,
required,
allow,
}
}
pub fn preval_paren(osrc: &str, csrc: &str) -> OpDef {
OpDef::paren(osrc, csrc).with_preval(preval(true, false, None))
}