lash_lashlang_runtime/
typed_output.rs1use serde_json::Value;
5
6pub fn parse_output_schema(value: Option<&Value>) -> Result<Option<Value>, String> {
19 lashlang::parse_output_schema(value)
20}
21
22#[cfg(test)]
23mod tests {
24 use serde_json::json;
25
26 use super::*;
27 use crate::LASH_TYPE_KEY;
28
29 #[test]
30 fn output_schema_supports_scalars_and_lists() {
31 let schema = parse_output_schema(Some(&json!({
32 "answer": "str",
33 "count": "int",
34 "items": "list[str]"
35 })))
36 .expect("schema")
37 .expect("present");
38 assert_eq!(schema["properties"]["answer"]["type"], json!("string"));
39 assert_eq!(schema["properties"]["count"]["type"], json!("integer"));
40 assert_eq!(schema["properties"]["items"]["type"], json!("array"));
41 }
42
43 #[test]
44 fn output_schema_passes_through_lash_type_wrapper() {
45 let inner_schema = json!({
46 "type": "object",
47 "properties": {
48 "name": { "type": "string" },
49 "tags": { "type": "array", "items": { "type": "string" } },
50 "status": { "type": "string", "enum": ["ok", "err"] }
51 },
52 "required": ["name", "tags", "status"],
53 "additionalProperties": false
54 });
55 let wrapped = json!({ LASH_TYPE_KEY: inner_schema.clone() });
56 let schema = parse_output_schema(Some(&wrapped))
57 .expect("schema")
58 .expect("present");
59 assert_eq!(schema, inner_schema);
60 }
61
62 #[test]
63 fn output_schema_rejects_lash_type_without_type_field() {
64 let wrapped = json!({ LASH_TYPE_KEY: {"properties": {}} });
65 let err = parse_output_schema(Some(&wrapped)).expect_err("missing type");
66 assert!(err.contains("type"), "error: {err}");
67 }
68
69 #[test]
70 fn output_schema_accepts_array_top_level_type() {
71 let wrapped = json!({
72 LASH_TYPE_KEY: {
73 "type": "array",
74 "items": {"type": "string"}
75 }
76 });
77 let schema = parse_output_schema(Some(&wrapped))
78 .expect("schema")
79 .expect("present");
80 assert_eq!(schema["type"], json!("array"));
81 }
82}