# llm_xml_caster: Robust XML Caster for LLM Structured Output in Rust
[](https://crates.io/crates/llm_xml_caster)
[](https://github.com/vintcessun/llm_xml_caster/blob/main/LICENSE)
[](https://docs.rs/llm_xml_caster)
`llm_xml_caster` is a powerful and reliable Rust library designed to simplify the process of extracting structured data from Large Language Models (LLMs) via XML. By leveraging Rust's type system and procedural macros, it enables developers to define data structures once and automatically generate precise XML schemas and prompts for LLMs, ensuring high-fidelity data casting.
## Features
- **Schema Generation**: Automatically generates detailed XML schemas (including descriptions) from Rust structs and enums for precise LLM prompting.
- **Type Safety**: Integrates seamlessly with `serde` for safe and efficient deserialization.
- **Rich Type Support**: Supports basic types, nested structs, enums, `Vec<T>`, `Option<T>`, and more.
- **LLM Integration**: Provides utilities like `generate_as` and `generate_as_with_retries` for direct interaction (requires setting up the `genai` dependency).
## Installation
Add the following to your `Cargo.toml`:
```toml
[dependencies]
llm_xml_caster = "0.1.0" # Current version, check crates.io for the latest
serde = { version = "1.0", features = ["derive"] }
```
## Usage Example: Defining and Using Prompts
The core functionality is provided by the `#[llm_prompt]` procedural macro and the `LlmPrompt` trait.
### 1. Define Your Structure
Use `#[llm_prompt]` on your struct, and use `#[prompt("...")]` on fields to provide descriptions that guide the LLM's output.
```rust
use llm_xml_caster::{llm_prompt, LlmPrompt};
use serde::Deserialize;
#[llm_prompt]
#[derive(Deserialize, Debug, PartialEq)]
pub struct SimpleStruct {
#[prompt("The name of the person")]
name: String,
#[prompt("The age of the person")]
age: i32,
#[prompt("Whether the person is a student (true/false, yes/no)")]
is_student: bool,
}
```
### 2. Generate the XML Schema for LLM Prompting
The `LlmPrompt` trait is automatically implemented, allowing you to retrieve the schema required by the LLM:
```rust
let schema = SimpleStruct::get_prompt_schema();
// The schema output will be a detailed XML structure with descriptions:
// <SimpleStruct>
// <name> <!-- The name of the person --> </name>
// <age> <!-- The age of the person --> </age>
// <is_student> <!-- Whether the person is a student (true/false, yes/no) --> </is_student>
// </SimpleStruct>
// Also get the root element name:
let root_name = SimpleStruct::root_name(); // "SimpleStruct"
```
### 3. Deserialize the LLM's XML Output
Use `quick-xml` (or similar deserializers) with the output generated by the LLM:
```rust
use quick_xml::de::from_str;
let xml_output = r#"
<SimpleStruct>
<name><![CDATA[John Doe]]></name>
<age>30</age>
<is_student>yes</is_student>
</SimpleStruct>
"#;
let decoded: SimpleStruct = from_str(xml_output).unwrap();
assert_eq!(decoded.name, "John Doe".to_string());
assert_eq!(decoded.is_student, true); // Custom casting logic handles 'yes'
```
## Advanced Types (Enums and Collections)
The macro handles complex types automatically:
### Nested Structs
```rust
// Requires SimpleStruct to also implement LlmPrompt
#[llm_prompt]
#[derive(Deserialize, Debug, PartialEq)]
struct NestedStruct {
#[prompt("The person details")]
person: SimpleStruct,
#[prompt("The score of the person")]
score: f32,
}
```
### Collections (Vectors and Options)
```rust
#[llm_prompt]
#[derive(Deserialize, Debug, PartialEq)]
struct CollectionsStruct {
#[prompt("A list of strings")]
tags: Vec<String>, // Automatically generates repeated <item> elements
#[prompt("An optional description")]
description: Option<String>, // Automatically handles optional presence
}
```
### Enums (Sum Types)
```rust
#[llm_prompt]
#[derive(Deserialize, Debug, PartialEq)]
enum TestEnum {
#[prompt("A simple variant")]
Simple, // Generated as <Simple/>
#[prompt("A variant with data")]
WithData {
#[prompt("The value of the variant")]
value: i32,
}, // Generated as <WithData><value>...</value></WithData>
}
```
## Contributing
We welcome contributions! Please check the issues and pull requests on [GitHub](https://github.com/vintcessun/llm_xml_caster).
## License
This project is licensed under the MIT License. See the [LICENSE](https://github.com/vintcessun/llm_xml_caster/blob/main/LICENSE) file for details.