1use sim_kernel::{Cx, Expr, Result, ShapeRef, Symbol};
2
3pub fn shape_to_json_schema(cx: &mut Cx, shape: Option<&ShapeRef>) -> Result<Expr> {
9 let Some(shape) = shape else {
10 return Ok(any_schema());
11 };
12 let expr = shape.object().as_expr(cx)?;
13 Ok(schema_from_shape_expr(&expr))
14}
15
16fn schema_from_shape_expr(expr: &Expr) -> Expr {
17 match expr {
18 Expr::Symbol(symbol) if symbol == &Symbol::qualified("core", "Any") => any_schema(),
19 Expr::Symbol(symbol) if symbol == &Symbol::qualified("core", "String") => {
20 typed_schema("string")
21 }
22 Expr::Symbol(symbol) if symbol == &Symbol::qualified("core", "Number") => {
23 typed_schema("number")
24 }
25 Expr::Symbol(symbol) if symbol == &Symbol::qualified("core", "Bool") => {
26 typed_schema("boolean")
27 }
28 Expr::Symbol(symbol) if symbol == &Symbol::qualified("core", "Nil") => typed_schema("null"),
29 Expr::Symbol(symbol) => schema_with_sim_shape(symbol.to_string()),
30 _ => schema_with_sim_shape(format!("{expr:?}")),
31 }
32}
33
34fn any_schema() -> Expr {
35 Expr::Map(Vec::new())
36}
37
38fn typed_schema(kind: &str) -> Expr {
39 Expr::Map(vec![field("type", Expr::String(kind.to_owned()))])
40}
41
42fn schema_with_sim_shape(shape: String) -> Expr {
43 Expr::Map(vec![field("x-sim-shape", Expr::String(shape))])
44}
45
46use sim_value::build::entry as field;