jsonschema_annotator/
lib.rs

1#![doc = include_str!("../README.md")]
2
3mod annotator;
4mod error;
5mod format;
6mod schema;
7
8pub use annotator::{Annotator, AnnotatorConfig, TomlAnnotator, YamlAnnotator};
9pub use error::{AnnotatorError, AnnotatorErrorKind, Error, ResultExt, SchemaError, SchemaErrorKind};
10pub use format::TargetFormat;
11pub use schema::{extract_annotations, Annotation, AnnotationMap};
12
13use schemars::Schema;
14
15/// Annotate a target document with schema descriptions
16///
17/// # Arguments
18/// * `schema` - JSON Schema as a `schemars::Schema`
19/// * `target` - Target document as a string (TOML or YAML)
20/// * `target_format` - Format of the target document
21/// * `config` - Annotation configuration options
22///
23/// # Example
24/// ```rust
25/// use jsonschema_annotator::{annotate, TargetFormat, AnnotatorConfig};
26/// use schemars::Schema;
27///
28/// let schema_json = r#"{"properties": {"port": {"title": "Port"}}}"#;
29/// let schema: Schema = serde_json::from_str(schema_json).unwrap();
30///
31/// let annotated = annotate(
32///     &schema,
33///     "port = 8080",
34///     TargetFormat::Toml,
35///     AnnotatorConfig::default(),
36/// ).unwrap();
37///
38/// assert!(annotated.contains("# Port"));
39/// ```
40pub fn annotate(
41    schema: &Schema,
42    target: &str,
43    target_format: TargetFormat,
44    config: AnnotatorConfig,
45) -> Result<String, AnnotatorError> {
46    let annotations = extract_annotations(schema);
47
48    match target_format {
49        TargetFormat::Toml => {
50            let annotator = TomlAnnotator::new(config);
51            annotator.annotate(target, &annotations)
52        }
53        TargetFormat::Yaml => {
54            let annotator = YamlAnnotator::new(config);
55            annotator.annotate(target, &annotations)
56        }
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63    use insta::assert_snapshot;
64
65    #[test]
66    fn test_annotate_toml() {
67        let schema_json = r#"{
68            "properties": {
69                "server": {
70                    "title": "Server",
71                    "description": "Server configuration",
72                    "properties": {
73                        "port": {
74                            "title": "Port",
75                            "description": "The port to listen on"
76                        }
77                    }
78                }
79            }
80        }"#;
81
82        let schema: Schema = serde_json::from_str(schema_json).unwrap();
83        let config = r#"[server]
84port = 8080
85"#;
86
87        let result = annotate(&schema, config, TargetFormat::Toml, AnnotatorConfig::default()).unwrap();
88        assert_snapshot!(result);
89    }
90
91    #[test]
92    fn test_annotate_yaml() {
93        let schema_json = r#"{
94            "properties": {
95                "server": {
96                    "title": "Server",
97                    "description": "Server configuration",
98                    "properties": {
99                        "port": {
100                            "title": "Port",
101                            "description": "The port to listen on"
102                        }
103                    }
104                }
105            }
106        }"#;
107
108        let schema: Schema = serde_json::from_str(schema_json).unwrap();
109        let config = r#"server:
110  port: 8080
111"#;
112
113        let result = annotate(&schema, config, TargetFormat::Yaml, AnnotatorConfig::default()).unwrap();
114        assert_snapshot!(result);
115    }
116
117    #[test]
118    fn test_annotate_with_refs() {
119        let schema_json = r##"{
120            "$defs": {
121                "Port": {
122                    "title": "Port",
123                    "description": "A network port number"
124                }
125            },
126            "properties": {
127                "http_port": { "$ref": "#/$defs/Port" },
128                "https_port": { "$ref": "#/$defs/Port" }
129            }
130        }"##;
131
132        let schema: Schema = serde_json::from_str(schema_json).unwrap();
133        let config = "http_port = 80\nhttps_port = 443\n";
134
135        let result = annotate(&schema, config, TargetFormat::Toml, AnnotatorConfig::default()).unwrap();
136        assert_snapshot!(result);
137    }
138}