use crate::graph;
use crate::query;
use super::{
impact_model_fields, impact_outcome, imported_section_fields, member_refs_fields,
read_model_fields, refs_model_fields, tests_model::tests_model_fields, J,
};
pub(super) fn j_next(next: &[Vec<String>]) -> J {
J::Arr(
next.iter()
.map(|argv| J::Arr(argv.iter().map(|a| J::Str(a.clone())).collect()))
.collect(),
)
}
fn with_next(mut fields: Vec<(&'static str, J)>, next: &[Vec<String>]) -> Vec<(&'static str, J)> {
let outcome = fields
.pop()
.filter(|(key, _)| *key == "outcome")
.expect("`next` is placed by swapping the trailing `outcome` field");
fields.push(("next", j_next(next)));
fields.push(outcome);
fields
}
fn refs_j_with_next(model: &query::RefsModel, outcome: query::Outcome, next: &[Vec<String>]) -> J {
J::Obj(with_next(refs_model_fields(model, outcome), next))
}
pub(crate) fn refs_model_to_json_with_next(
model: &query::RefsModel,
next: &[Vec<String>],
) -> String {
refs_j_with_next(model, query::Outcome::Hit, next).to_json_string()
}
pub(crate) fn read_model_to_json_with_next(
model: &query::ReadModel,
next: &[Vec<String>],
) -> String {
J::Obj(with_next(read_model_fields(model), next)).to_json_string()
}
pub(crate) fn tests_model_to_json_with_next(
model: &query::TestsModel,
next: &[Vec<String>],
) -> String {
J::Obj(with_next(tests_model_fields(model), next)).to_json_string()
}
fn impact_j_with_next(
mut fields: Vec<(&'static str, J)>,
outcome: query::Outcome,
next: &[Vec<String>],
) -> J {
fields.push(("next", j_next(next)));
fields.push(("outcome", J::Str(outcome.as_str().to_string())));
J::Obj(fields)
}
pub(crate) fn impact_model_to_json_with_next(
query_str: &str,
model: &query::ImpactModel,
next: &[Vec<String>],
) -> String {
let fields = impact_model_fields(query_str, model);
impact_j_with_next(fields, impact_outcome(model, false), next).to_json_string()
}
pub(crate) fn impact_model_to_json_with_imports_and_next(
query_str: &str,
model: &query::ImpactModel,
imported: &query::ImportedSection,
provenance: &graph::Provenance,
next: &[Vec<String>],
) -> String {
let fields: Vec<(&'static str, J)> = impact_model_fields(query_str, model)
.into_iter()
.chain(imported_section_fields(imported, provenance))
.collect();
let outcome = impact_outcome(model, !imported.rows.is_empty());
impact_j_with_next(fields, outcome, next).to_json_string()
}
pub(crate) fn member_refs_to_json_with_next(
query_str: &str,
models: &[query::RefsModel],
outcome: query::Outcome,
members_next: &[Vec<Vec<String>>],
wrapper_next: &[Vec<String>],
) -> String {
let members: Vec<J> = models
.iter()
.zip(members_next)
.map(|(model, next)| refs_j_with_next(model, outcome, next))
.collect();
J::Obj(member_refs_fields(
query_str,
members,
Some(wrapper_next),
outcome,
))
.to_json_string()
}