Skip to main content

claude_code/
structured.rs

1use schemars::{JsonSchema, schema_for};
2
3use crate::error::ClaudeError;
4
5/// Generates a JSON Schema string from a type implementing [`JsonSchema`].
6///
7/// Use the result with [`ClaudeConfigBuilder::json_schema`](crate::ClaudeConfigBuilder::json_schema)
8/// to enable structured output from the CLI.
9///
10/// # Errors
11///
12/// Returns [`ClaudeError::ParseError`] if schema serialization fails.
13pub fn generate_schema<T: JsonSchema>() -> Result<String, ClaudeError> {
14    let schema = schema_for!(T);
15    serde_json::to_string(&schema).map_err(ClaudeError::from)
16}
17
18#[cfg(test)]
19mod tests {
20    use super::*;
21
22    #[allow(dead_code)]
23    #[derive(schemars::JsonSchema)]
24    struct TestStruct {
25        name: String,
26        count: i32,
27    }
28
29    #[test]
30    fn generate_schema_returns_valid_json() {
31        let schema_str = generate_schema::<TestStruct>().unwrap();
32        let value: serde_json::Value = serde_json::from_str(&schema_str).unwrap();
33        assert!(value.is_object());
34    }
35
36    #[test]
37    fn generate_schema_contains_properties() {
38        let schema_str = generate_schema::<TestStruct>().unwrap();
39        let value: serde_json::Value = serde_json::from_str(&schema_str).unwrap();
40        let props = value.get("properties").expect("should have properties");
41        assert!(props.get("name").is_some());
42        assert!(props.get("count").is_some());
43    }
44}