1use serde::{Deserialize, Serialize};
7
8use crate::registry::Registry;
9use crate::violation::Violation;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub enum Request {
13 Registry,
15 Validate {
19 entries: Vec<(String, String)>,
20 systems: Vec<String>,
21 },
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub enum Response {
26 Registry(Registry),
27 Violations(Vec<Violation>),
28 Error(String),
30}
31
32pub fn serve_schema(
36 registry: impl Fn() -> crate::registry::Registry,
37 validate: impl Fn(&[(String, String)], &[&str]) -> Vec<crate::violation::Violation>,
38) {
39 use std::io::Read;
40 let respond = |r: &Response| match crate::ronfmt::to_ron(r) {
41 Ok(text) => print!("{text}"),
42 Err(e) => {
43 eprintln!("serializing response: {e}");
44 std::process::exit(2);
45 }
46 };
47 let mut input = String::new();
48 if let Err(e) = std::io::stdin().read_to_string(&mut input) {
49 respond(&Response::Error(format!("reading stdin: {e}")));
50 std::process::exit(2);
51 }
52 let response = match ron::from_str::<Request>(&input) {
53 Err(e) => Response::Error(format!("parsing request: {e}")),
54 Ok(Request::Registry) => Response::Registry(registry()),
55 Ok(Request::Validate { entries, systems }) => {
56 let systems: Vec<&str> = systems.iter().map(String::as_str).collect();
57 Response::Violations(validate(&entries, &systems))
58 }
59 };
60 respond(&response);
61}