Rschema

Rschema provides a macro for generating JSON schemas from Rust structures.
Description
Often, you will use a framework such as serde to deserialize the contents of a configuration file into a Rust structure.
This tool generates schema information for the target file from the structure to be deserialized.
This supports pre-validation of the configuration file.
Example code
use rschema::{
Schema,
Schematic,
};
use serde::Deserialize;
#[derive(Debug, Schematic, Deserialize)]
#[rschema(additional_properties)]
struct Custom {
#[rschema(field(
title = "A flag for debugging",
description = "Set `true` to display debug logs.",
))]
debug_flag: bool,
}
#[derive(Debug, Schematic, Deserialize)]
struct AppConfig {
#[rschema(
field(
title = "Application Config",
description = "Application configuration file.",
),
required,
)]
app_name: String,
#[rschema(
field(
title = "Version",
description = "Application version.",
pattern = r"^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$",
),
required,
)]
version: String,
#[rschema(field(
title = "Custom Configuration",
description = "Additional custom configuration.",
))]
custom: Custom,
}
fn main() -> rschema::Result<()> {
Schema::new::<Config>("Application Config")
.description("Application configuration file.")
.write_pretty("config.schema.json")?;
Ok(())
}
The above code generates the following file:
{
"title": "Application Config",
"description": "Application configuration file.",
"type": "object",
"properties": {
"app_name": {
"title": "Application Config",
"description": "Application configuration file.",
"type": "string"
},
"version": {
"title": "Version",
"description": "Application version.",
"type": "string",
"pattern": "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$"
},
"custom": {
"title": "Custom Configuration",
"description": "Additional custom configuration.",
"type": "object",
"properties": {
"debug_flag": {
"title": "A flag for debugging",
"description": "Set `true` to display debug logs.",
"type": "boolean"
}
},
"additionalProperties": true
}
},
"required": [
"app_name",
"version"
],
"additionalProperties": false
}
It can be used with support tools such as VSCode.
Combination with serde
Rschema and Serde can be used together.
Files that pass validation with the JSON schema generated by Rschema will be always successfully deserialized to the same data.
fn main() -> std::io::Result<()> {
let config_json_str = std::fs::read("config.json")?;
let config: Config = serde_json::from_str(&config_json_str).unwrap();
Ok(())
}