use serde::{Deserialize, Serialize};
use crate::registry::Registry;
use crate::violation::Violation;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Request {
Registry,
Validate {
entries: Vec<(String, String)>,
systems: Vec<String>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Response {
Registry(Registry),
Violations(Vec<Violation>),
Error(String),
}
pub fn serve_schema(
registry: impl Fn() -> crate::registry::Registry,
validate: impl Fn(&[(String, String)], &[&str]) -> Vec<crate::violation::Violation>,
) {
use std::io::Read;
let respond = |r: &Response| match crate::ronfmt::to_ron(r) {
Ok(text) => print!("{text}"),
Err(e) => {
eprintln!("serializing response: {e}");
std::process::exit(2);
}
};
let mut input = String::new();
if let Err(e) = std::io::stdin().read_to_string(&mut input) {
respond(&Response::Error(format!("reading stdin: {e}")));
std::process::exit(2);
}
let response = match ron::from_str::<Request>(&input) {
Err(e) => Response::Error(format!("parsing request: {e}")),
Ok(Request::Registry) => Response::Registry(registry()),
Ok(Request::Validate { entries, systems }) => {
let systems: Vec<&str> = systems.iter().map(String::as_str).collect();
Response::Violations(validate(&entries, &systems))
}
};
respond(&response);
}