3 releases
Uses new Rust 2024
| 0.1.2 | Jul 13, 2025 |
|---|---|
| 0.1.1 | Mar 31, 2025 |
| 0.1.0 | Mar 31, 2025 |
#8 in #doc-comment
1,121 downloads per month
Used in 110 crates
(5 directly)
470KB
9K
SLoC
ai-json-template-derive
A proc-macro crate that allows you to derive a trait, AiJsonTemplate, on any plain-old Rust struct to produce a JSON “schema” or “template” describing that struct’s fields, doc comments, and nested structures. This crate enforces certain field types—such as String, Option<String>, Vec<String>, or a recursively nested type also deriving AiJsonTemplate—making it useful for guiding AI models (like GPT) to output data matching a specific format.
Features
-
AiJsonTemplateTrait- Automatically implemented via
#[derive(AiJsonTemplate)]. - Provides a single method,
to_template(), returning aserde_json::Valuedescribing each field’s type and any doc comments.
- Automatically implemented via
-
Doc Comments to Instructions
- Rust doc comments (
///) on structs and fields become embedded in the JSON output, helping you generate AI instructions or clarifications.
- Rust doc comments (
-
Nested Struct Support
- If a field’s type also derives
AiJsonTemplate, the macro includes a"nested_template"object in the JSON.
- If a field’s type also derives
-
Controlled Field Types
- By default, only
String,Option<String>,Vec<String>, or nestedAiJsonTemplatetypes are allowed. The macro fails if it encounters other field types, ensuring consistent data structures for AI outputs.
- By default, only
-
Seamless with Serde
- You can also derive
SerializeandDeserializeon the same struct. The macro doesn’t interfere with normal Rust <-> JSON round-trip usage.
- You can also derive
Example
use ai_json_template_derive::AiJsonTemplate;
use serde::{Serialize, Deserialize};
#[derive(AiJsonTemplate, Serialize, Deserialize)]
/// My top-level config struct
pub struct TopLevelConfig {
/// Plain string field, always required
title: String,
/// Optional field for additional notes
notes: Option<String>,
/// Another struct, nested
nested: SubConfig,
}
#[derive(AiJsonTemplate, Serialize, Deserialize)]
/// A nested struct, also with doc comments
pub struct SubConfig {
/// A short summary
summary: String,
/// Multiple tags
tags: Vec<String>,
}
fn main() {
// Generate the template describing fields + doc comments
let schema = TopLevelConfig::to_template();
println!("JSON template:\n{}",
serde_json::to_string_pretty(&schema).unwrap()
);
}
Output might look like:
{
"struct_name": "TopLevelConfig",
"struct_docs": "My top-level config struct",
"fields": {
"title": {
"type": "string",
"generation_instructions": "Plain string field, always required",
"required": true
},
"notes": {
"type": "string",
"generation_instructions": "Optional field for additional notes",
"required": false
},
"nested": {
"type": "nested_struct",
"generation_instructions": "Another struct, nested",
"required": true,
"nested_template": {
"struct_name": "SubConfig",
"struct_docs": "A nested struct, also with doc comments",
"fields": {
"summary": {
"type": "string",
"generation_instructions": "A short summary",
"required": true
},
"tags": {
"type": "array_of_strings",
"generation_instructions": "Multiple tags",
"required": true
}
}
}
}
}
}
Installation
In your Cargo.toml, add:
[dependencies]
ai-json-template-derive = "0.1"
serde = "1.0"
serde_json = "1.0"
Note: Because it’s a proc-macro crate, ensure you have Rust 2021 edition or later. You’ll also need
syn,quote, andproc-macro2available internally.
Usage
- Import the macro:
use ai_json_template_derive::AiJsonTemplate; - Annotate structs with
#[derive(AiJsonTemplate, Serialize, Deserialize)]. - Generate JSON: call
YourStruct::to_template()to retrieve a structured schema of doc comments and types. - Feed that JSON schema to an AI model to guide output format, or use it as you see fit.
Testing
We provide a robust integration test suite in the tests/ folder, covering:
- Simple usage with required and optional fields.
- Nested structs (multi-level).
- Doc comments verification.
- Round-trip checks ensuring normal Serde usage is unaffected.
You can also add [trybuild] tests to confirm that the macro fails gracefully when encountering unsupported field types or missing Serialize/Deserialize derivations.
Dependencies
~12–28MB
~277K SLoC