#![allow(dead_code)]
#![allow(clippy::result_large_err)]
use std::path::{Path, PathBuf};
use serde_json::Value as Json;
use tabnas::{CommentDef, Tabnas, Value, ValueDef};
use tabnas_csv::CsvOptions;
use tabnas_support::Failure;
pub fn repo_root() -> &'static Path {
Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("rs/ has a parent")
}
pub fn fixtures_dir() -> PathBuf {
repo_root().join("test").join("fixtures")
}
pub fn parser_for(options: serde_json::Value) -> Tabnas {
let mut parser = tabnas_jsonic::make();
parser
.use_plugin(tabnas_csv::plugin(), Some(Value::from_json(&options)))
.unwrap_or_else(|error| panic!("csv plugin: {error}"));
parser
}
pub fn parser_with(options: CsvOptions) -> Tabnas {
tabnas_csv::make_with(options)
}
pub fn to_json(value: &Value) -> serde_json::Value {
value.to_json()
}
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_json(
src: &str,
options: serde_json::Value,
) -> Result<serde_json::Value, tabnas::TabnasError> {
parser_for(options).parse(src).map(|value| to_json(&value))
}
pub fn parse_default(src: &str) -> Result<serde_json::Value, tabnas::TabnasError> {
parse_json(src, serde_json::json!({}))
}
pub fn apply_jsonic_options(parser: &mut Tabnas, jsonic_opt: &Json) {
parser
.set_options(|options| {
if let Some(defs) = jsonic_opt.pointer("/value/def").and_then(Json::as_object) {
for (name, def) in defs {
match def {
Json::Null => {
options.value.definitions.shift_remove(name);
}
Json::Object(fields) => {
options.value.definitions.insert(
name.clone(),
ValueDef {
val: Some(Value::from_json(
fields.get("val").unwrap_or(&Json::Null),
)),
matcher: None,
transform: None,
consume: false,
},
);
}
other => panic!("value.def.{name}: unsupported {other}"),
}
}
}
if let Some(defs) = jsonic_opt.pointer("/comment/def").and_then(Json::as_object) {
for (name, def) in defs {
let fields = def
.as_object()
.unwrap_or_else(|| panic!("comment.def.{name}"));
let start = fields.get("start").and_then(Json::as_str).unwrap_or("");
let end = fields.get("end").and_then(Json::as_str);
options.comment.definitions.insert(
name.clone(),
CommentDef {
line: end.is_none(),
start: start.to_string(),
end: end.unwrap_or("").to_string(),
lex: true,
suffixes: Vec::new(),
suffix_matcher: None,
eat_line: false,
},
);
}
}
})
.expect("the jsonic options apply");
}
pub fn fixture_parser(options: &Json, jsonic_opt: Option<&Json>) -> Tabnas {
let mut parser = tabnas_jsonic::make();
if let Some(jsonic_opt) = jsonic_opt {
apply_jsonic_options(&mut parser, jsonic_opt);
}
parser
.use_plugin(tabnas_csv::plugin(), Some(Value::from_json(options)))
.expect("the csv plugin installs");
parser
}