### rstructor String Field Examples Source: https://github.com/clifton/rstructor/blob/main/EXAMPLES.md Shows various ways to provide descriptions and examples for String fields using rstructor attributes. Supports single examples, multiple examples using native array syntax, and legacy JSON array syntax. ```rust // String examples #[llm(description = "The name of the person", example = "John Smith")] name: String, // Multiple examples using native array syntax (recommended) #[llm(description = "The full name", examples = ["John Smith", "Jane Doe", "Alex Johnson"])] full_name: String, // You can also still use JSON array syntax for backward compatibility #[llm(description = "The full name", example = "[\"John Smith\", \"Jane Doe\"]")] legacy_name: String, ``` -------------------------------- ### Install rstructor with LLM Provider Features Source: https://context7.com/clifton/rstructor/llms.txt Add rstructor to your Cargo.toml file, specifying the desired LLM provider features (e.g., 'openai', 'anthropic', 'grok', 'gemini'). This example also includes serde for serialization/deserialization and tokio for asynchronous operations. ```toml [dependencies] rstructor = { version = "0.2", features = ["openai", "anthropic", "grok", "gemini"] } serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] } ``` -------------------------------- ### Running Rstructor Examples (Bash) Source: https://github.com/clifton/rstructor/blob/main/README.md Provides bash commands to run example applications included with the rstructor library. These examples demonstrate various functionalities, such as structured movie info extraction and handling nested objects. ```bash export OPENAI_API_KEY=your_key cargo run --example structured_movie_info cargo run --example nested_objects_example cargo run --example enum_with_data_example cargo run --example serde_rename_example ``` -------------------------------- ### Raw Text Generation in Rust with Rstructor Source: https://context7.com/clifton/rstructor/llms.txt Demonstrates generating unstructured text responses without schema constraints using the `generate` function. This is useful for creative writing or when a specific data structure is not required. The example also shows how to get metadata, including token usage, for raw text generation. ```rust use rstructor::{LLMClient, OpenAIClient}; #[tokio::main] async fn main() -> Result<(), Box> { let client = OpenAIClient::from_env()?; // Simple text generation let poem = client.generate("Write a haiku about programming").await?; println!("Haiku:\n{}", poem); // With metadata let result = client .generate_with_metadata("Explain recursion in one sentence") .await?; println!("\nExplanation: {}", result.text); if let Some(usage) = result.usage { println!("Tokens used: {}", usage.total_tokens()); } Ok(()) } ``` -------------------------------- ### Quick Start: Extract Movie Data with rstructor and OpenAI Source: https://github.com/clifton/rstructor/blob/main/README.md Demonstrates a basic usage of rstructor to extract structured 'Movie' data from an LLM using OpenAI. It defines a 'Movie' struct with LLM-specific descriptions and examples, then uses an OpenAI client to materialize the data from a prompt. ```rust use rstructor::{Instructor, LLMClient, OpenAIClient}; use serde::{Deserialize, Serialize}; #[derive(Instructor, Serialize, Deserialize, Debug)] struct Movie { #[llm(description = "Title of the movie")] title: String, #[llm(description = "Director of the movie")] director: String, #[llm(description = "Year released", example = 2010)] year: u16, } #[tokio::main] async fn main() -> Result<(), Box> { let client = OpenAIClient::from_env()? .temperature(0.0); let movie: Movie = client.materialize("Tell me about Inception").await?; println!("{}: {} ({})", movie.title, movie.director, movie.year); Ok(()) } ``` -------------------------------- ### rstructor Array/Vector Field Examples Source: https://github.com/clifton/rstructor/blob/main/EXAMPLES.md Shows how to provide descriptions and examples for array and vector fields using rstructor attributes. Supports native Rust array literals, JSON-like string arrays, and mixed types. ```rust // For arrays, you can now use native Rust array literals (recommended) #[llm(description = "List of tags", example = ["important", "urgent", "follow-up"])] tags: Vec, // For number arrays with native array syntax #[llm(description = "List of scores", example = [90, 85, 76, 92])] scores: Vec, // You can also still use the JSON-like array string with single quotes for backward compatibility #[llm(description = "List of categories", example = "['important', 'urgent', 'follow-up']")] categories: Vec, // Mixed types are also supported in array literals #[llm(description = "Mixed data", example = ["text", 123, true, 45.6])] mixed_data: Vec, ``` -------------------------------- ### rstructor Object Field Example Source: https://github.com/clifton/rstructor/blob/main/EXAMPLES.md Illustrates how to provide a description and example for a complex object field using rstructor attributes. JSON object syntax is used for the example. ```rust // For complex objects, use JSON object syntax #[llm(description = "The user's address", example = "{\"street\": \"123 Main St\", \"city\": \"New York\", \"zip\": \"10001\"}")] address: Address, ``` -------------------------------- ### Fetching Gemini Models via cURL Source: https://github.com/clifton/rstructor/blob/main/CLAUDE.md This command queries the Google Gemini API to get a list of available models. The API key is passed as a query parameter. ```bash curl "https://generativelanguage.googleapis.com/v1beta/models?key=$GEMINI_API_KEY" ``` -------------------------------- ### Instructor Derive Macro for LLM Structured Output in Rust Source: https://context7.com/clifton/rstructor/llms.txt The `Instructor` derive macro generates JSON schemas from Rust structs and enums, allowing LLMs to produce type-safe structured output. Use `#[llm(...)]` attributes for descriptions, examples, and validation rules to guide the LLM. ```rust use rstructor::{Instructor, LLMClient, OpenAIClient}; use serde::{Deserialize, Serialize}; #[derive(Instructor, Serialize, Deserialize, Debug)] #[llm(description = "Detailed information about a movie")] struct Movie { #[llm(description = "Title of the movie")] title: String, #[llm(description = "Director of the movie", example = "Christopher Nolan")] director: String, #[llm(description = "Year the movie was released", example = 2010)] release_year: u16, #[llm(description = "List of genres", example = ["Drama", "Thriller"])] genres: Vec, #[llm(description = "IMDB rating out of 10", example = 8.5)] rating: f32, } #[tokio::main] async fn main() -> Result<(), Box> { let client = OpenAIClient::from_env()?; let movie: Movie = client.materialize("Tell me about the movie Inception").await?; println!("Title: {}", movie.title); println!("Director: {}", movie.director); println!("Year: {}", movie.release_year); println!("Genres: {:?}", movie.genres); println!("Rating: {:.1}/10", movie.rating); Ok(()) } ``` -------------------------------- ### OpenAI Client for Local LLMs and OpenAI-Compatible APIs Source: https://context7.com/clifton/rstructor/llms.txt Connects to local LLMs (e.g., Ollama, LM Studio, vLLM) or any OpenAI-compatible API by setting a custom base URL. An API key is still required but can be a placeholder for local setups. ```rust use rstructor::{Instructor, LLMClient, OpenAIClient}; use serde::{Deserialize, Serialize}; #[derive(Instructor, Serialize, Deserialize, Debug)] struct Response { answer: String, confidence: f32, } #[tokio::main] async fn main() -> Result<(), Box> { // Connect to local LLM (e.g., Ollama, LM Studio, vLLM) let client = OpenAIClient::new("not-needed-for-local")? .base_url("http://localhost:1234/v1") .model("llama-3.1-70b") .temperature(0.0); let response: Response = client .materialize("What is the capital of France?") .await?; println!("Answer: {} (confidence: {:.0}%)", response.answer, response.confidence * 100.0); Ok(()) } ``` -------------------------------- ### rstructor Optional Field Example Source: https://github.com/clifton/rstructor/blob/main/EXAMPLES.md Demonstrates how rstructor automatically detects optional fields from the `Option` type and how to provide descriptions and examples for them. ```rust // Optional fields are automatically detected from the Option type // No need to add an 'optional' attribute #[llm(description = "Optional middle name")] middle_name: Option, // Example for optional field #[llm(description = "Optional phone number", example = "+1-555-123-4567")] phone: Option, ``` -------------------------------- ### rstructor Number Field Examples Source: https://github.com/clifton/rstructor/blob/main/EXAMPLES.md Illustrates how to add descriptions and examples for integer and float number fields using rstructor attributes. Literals can be used directly without quotes for examples. ```rust // Integer example (can use literal without quotes) #[llm(description = "Age of the person", example = 30)] age: u32, // Float example (can use literal without quotes) #[llm(description = "Height in meters", example = 1.75)] height: f32, // Float with native array syntax for multiple examples #[llm(description = "Possible prices", examples = [45.99, 55.50, 32.99])] price: f32, ``` -------------------------------- ### Token Usage Tracking in Rust with Rstructor Source: https://context7.com/clifton/rstructor/llms.txt Shows how to track token usage for LLM calls using `materialize_with_metadata`. This is essential for cost monitoring and debugging API interactions. The example demonstrates accessing input, output, and total token counts from the result. ```rust use rstructor::{Instructor, LLMClient, OpenAIClient}; use serde::{Deserialize, Serialize}; #[derive(Instructor, Serialize, Deserialize, Debug)] struct Summary { title: String, key_points: Vec, word_count: u32, } #[tokio::main] async fn main() -> Result<(), Box> { let client = OpenAIClient::from_env()?; let result = client .materialize_with_metadata::("Summarize the benefits of Rust programming") .await?; println!("Summary: {}", result.data.title); println!("Key points: {:?}", result.data.key_points); if let Some(usage) = result.usage { println!("\n--- Token Usage ---"); println!("Model: {}", usage.model); println!("Input tokens: {}", usage.input_tokens); println!("Output tokens: {}", usage.output_tokens); println!("Total tokens: {}", usage.total_tokens()); } Ok(()) } ``` -------------------------------- ### Add Description to Struct and Enum with rstructor Source: https://github.com/clifton/rstructor/blob/main/EXAMPLES.md Demonstrates how to add a description attribute to a struct and an enum using the `llm` macro. This is useful for documenting the purpose of these types. ```rust #[derive(Instructor, Serialize, Deserialize, Debug)] #[llm(description = "Represents a person with their basic information")] struct Person { // Fields... } #[derive(Instructor, Serialize, Deserialize, Debug)] #[llm(description = "Represents a person's role in an organization")] enum Role { Employee, Manager, Director, } ``` -------------------------------- ### rstructor Simple Enum Example Source: https://github.com/clifton/rstructor/blob/main/EXAMPLES.md Shows how to define a simple enum with rstructor attributes, including descriptions for the enum itself and its variants. ```rust @derive(Instructor, Serialize, Deserialize, Debug) #[llm(description = "Sentiment of the text analysis")] enum Sentiment { #[llm(description = "The text is positive in tone")] Positive, #[llm(description = "The text is negative in tone")] Negative, #[llm(description = "The sentiment is neutral or mixed")] Neutral, } ``` -------------------------------- ### rstructor Boolean Field Example Source: https://github.com/clifton/rstructor/blob/main/EXAMPLES.md Demonstrates how to add a description and example for a boolean field using rstructor attributes. Boolean literals can be used directly without quotes. ```rust // Boolean example (can use literal without quotes) #[llm(description = "Whether the user is active", example = true)] is_active: bool, ``` -------------------------------- ### rstructor Enum with Simple Associated Data Example Source: https://github.com/clifton/rstructor/blob/main/EXAMPLES.md Demonstrates defining an enum with simple associated data types like strings and integers using rstructor attributes. ```rust @derive(Instructor, Serialize, Deserialize, Debug) enum UserStatus { #[llm(description = "The user is online")] Online, #[llm(description = "The user is offline")] Offline, #[llm(description = "The user is away with an optional message")] Away(String), #[llm(description = "The user is busy until a specific time")] Busy(u32), } ``` -------------------------------- ### Rstructor Error Handling with Retry Logic (Rust) Source: https://github.com/clifton/rstructor/blob/main/README.md Provides an example of robust error handling for rstructor operations, including checking for retryable errors and implementing backoff strategies. It also shows how to match specific API error kinds. ```rust use rstructor::{ApiErrorKind, RStructorError}; match client.materialize::("...").await { Ok(movie) => println!("{:?}", movie), Err(e) if e.is_retryable() => { println!("Transient error: {}", e); if let Some(delay) = e.retry_delay() { tokio::time::sleep(delay).await; } } Err(e) => match e.api_error_kind() { Some(ApiErrorKind::RateLimited { retry_after }) => { /* ... */ }, Some(ApiErrorKind::AuthenticationFailed) => { /* ... */ }, _ => eprintln!("Error: {}", e), } } ``` -------------------------------- ### Filtering OpenAI Chat Models Source: https://github.com/clifton/rstructor/blob/main/CLAUDE.md Example Python code to filter OpenAI models, including only those suitable for chat completions. It excludes models like whisper, text-embedding, and text-moderation. ```python def filter_openai_chat_models(model_ids): excluded_prefixes = ['whisper-', 'text-embedding-', 'text-moderation-'] return [model_id for model_id in model_ids if not any(model_id.startswith(prefix) for prefix in excluded_prefixes)] all_models = ['gpt-4-turbo', 'whisper-1', 'gpt-3.5-turbo', 'text-embedding-ada-002'] chat_models = filter_openai_chat_models(all_models) print(chat_models) ``` -------------------------------- ### rstructor Enum with Complex Associated Data Example Source: https://github.com/clifton/rstructor/blob/main/EXAMPLES.md Illustrates defining an enum with complex associated data types such as structs and nested enums, using rstructor attributes for documentation. ```rust // Defining structs used in enum variants #[derive(Serialize, Deserialize, Debug)] struct Address { street: String, city: String, zip: String, } #[derive(Serialize, Deserialize, Debug)] struct PaymentCard { card_number: String, exp_date: String, cvv: String, } // Enum with various types of associated data #[derive(Instructor, Serialize, Deserialize, Debug)] enum PaymentMethod { #[llm(description = "Payment made with a credit or debit card")] Card(PaymentCard), #[llm(description = "Payment made with PayPal")] PayPal(String), #[llm(description = "Payment will be made on delivery")] CashOnDelivery, #[llm(description = "Payment made via bank transfer with account details")] BankTransfer { account_number: String, routing_number: String, bank_name: String, }, } ``` -------------------------------- ### Parsing Gemini Model IDs Source: https://github.com/clifton/rstructor/blob/main/CLAUDE.md This Python code shows how to parse the Gemini API response to get model names. It extracts the 'name' field and removes the 'models/' prefix to get the clean model identifier. ```python import json response_json = '{"models": [{"name": "models/gemini-1.5-flash", ...}, {"name": "models/gemini-pro", ...}]}' data = json.loads(response_json) model_ids = [model['name'].replace('models/', '') for model in data.get('models', [])] print(model_ids) ``` -------------------------------- ### Parsing OpenAI Model IDs Source: https://github.com/clifton/rstructor/blob/main/CLAUDE.md Example of how to extract model identifiers from the JSON response of the OpenAI API. It iterates through the 'data' array and collects the 'id' field for each model. ```python import json response_json = '{"data": [{"id": "gpt-4-turbo", ...}, {"id": "gpt-3.5-turbo", ...}]}' data = json.loads(response_json) model_ids = [model['id'] for model in data.get('data', [])] print(model_ids) ``` -------------------------------- ### Implement Custom Validation with rstructor Source: https://github.com/clifton/rstructor/blob/main/README.md Shows how to add custom validation logic to rstructor models using the `llm(validate = ...)` attribute. This example defines a 'Movie' struct with validation for 'year' and 'rating', and a separate validation function `validate_movie`. It also demonstrates configuring retry behavior. ```rust use rstructor::{Instructor, RStructorError, Result}; #[derive(Instructor, Serialize, Deserialize)] #[llm(validate = "validate_movie")] struct Movie { title: String, year: u16, rating: f32, } fn validate_movie(movie: &Movie) -> Result<()> { if movie.year < 1888 || movie.year > 2030 { return Err(RStructorError::ValidationError( format!("Invalid year: {}", movie.year) )); } if movie.rating < 0.0 || movie.rating > 10.0 { return Err(RStructorError::ValidationError( format!("Rating must be 0-10, got {}", movie.rating) )); } Ok(()) } // Retries are enabled by default (3 attempts with error feedback) // To increase retries: let client = OpenAIClient::from_env()? .max_retries(5); // To disable retries: let client = OpenAIClient::from_env()? .no_retries(); ``` -------------------------------- ### Rust: Add Custom Validation with Retries using Rstructor Source: https://context7.com/clifton/rstructor/llms.txt This snippet shows how to add custom validation logic to a Rust struct using Rstructor. It defines a `Product` struct with validation rules and a `validate_product` function. The `#[llm(validate = "...")]` attribute links the validation function to the struct. The example also demonstrates configuring the `OpenAIClient` to retry operations on validation failures, with options to set the number of retries or disable them entirely. ```rust use rstructor::{Instructor, LLMClient, OpenAIClient, RStructorError, Result}; use serde::{Deserialize, Serialize}; #[derive(Instructor, Serialize, Deserialize, Debug)] #[llm(validate = "validate_product")] struct Product { #[llm(description = "Product name")] name: String, #[llm(description = "Price in USD", example = 29.99)] price: f64, #[llm(description = "Quantity in stock", example = 100)] quantity: u32, #[llm(description = "Product categories")] categories: Vec, } fn validate_product(product: &Product) -> Result<()> { if product.price <= 0.0 { return Err(RStructorError::ValidationError( format!("Price must be positive, got {}", product.price) )); } if product.name.trim().is_empty() { return Err(RStructorError::ValidationError( "Product name cannot be empty".to_string() )); } if product.categories.is_empty() { return Err(RStructorError::ValidationError( "Product must have at least one category".to_string() )); } Ok(()) } #[tokio::main] async fn main() -> Result<(), Box> { // Client retries up to 3 times by default on validation failure let client = OpenAIClient::from_env()?; .max_retries(5); // Increase retries for strict validation let product: Product = client .materialize("Describe a laptop computer product") .await?; println!("Product: {} - ${:.2}", product.name, product.price); println!("In stock: {}", product.quantity); println!("Categories: {:?}", product.categories); // Disable retries if needed let client_no_retry = OpenAIClient::from_env()?.no_retries(); Ok(()) } ``` -------------------------------- ### Configure LLM Providers with rstructor Source: https://github.com/clifton/rstructor/blob/main/README.md Illustrates how to initialize and configure clients for different LLM providers supported by rstructor, including OpenAI, Anthropic, Grok (xAI), and Gemini. It shows setting models and using environment variables for API keys, as well as configuring a custom endpoint. ```rust use rstructor::{OpenAIClient, AnthropicClient, GrokClient, GeminiClient, LLMClient}; // OpenAI (reads OPENAI_API_KEY) let client = OpenAIClient::from_env()? .model("gpt-5.2"); // Anthropic (reads ANTHROPIC_API_KEY) let client = AnthropicClient::from_env()? .model("claude-sonnet-4-5-20250929"); // Grok/xAI (reads XAI_API_KEY) let client = GrokClient::from_env()? .model("grok-4-1-fast-non-reasoning"); // Gemini (reads GEMINI_API_KEY) let client = GeminiClient::from_env()? .model("gemini-3-flash-preview"); // Custom endpoint (local LLMs, proxies) let client = OpenAIClient::new("key")? .base_url("http://localhost:1234/v1") .model("llama-3.1-70b"); ``` -------------------------------- ### OpenAIClient Configuration for LLM Interactions in Rust Source: https://context7.com/clifton/rstructor/llms.txt The `OpenAIClient` connects to OpenAI's API, supporting various GPT models. It allows configuration of parameters like model, temperature, max tokens, timeout, and thinking level for deterministic or complex reasoning outputs. ```rust use rstructor::{Instructor, LLMClient, OpenAIClient, OpenAIModel, ThinkingLevel}; use serde::{Deserialize, Serialize}; use std::time::Duration; #[derive(Instructor, Serialize, Deserialize, Debug)] struct Analysis { summary: String, key_points: Vec, sentiment: String, } #[tokio::main] async fn main() -> Result<(), Box> { // Create client from environment variable OPENAI_API_KEY let client = OpenAIClient::from_env()? .model(OpenAIModel::Gpt52) // Use GPT-5.2 (default) .temperature(0.0) // Deterministic output .max_tokens(1024) // Limit response length .timeout(Duration::from_secs(30)) // Set request timeout .thinking_level(ThinkingLevel::High); // Enable deep reasoning let analysis: Analysis = client .materialize("Analyze the impact of AI on software development") .await?; println!("Summary: {}", analysis.summary); println!("Key Points: {:?}", analysis.key_points); println!("Sentiment: {}", analysis.sentiment); // Or create with explicit API key let client = OpenAIClient::new("your-api-key")? .model("gpt-4o-mini"); // String model names also work Ok(()) } ``` -------------------------------- ### Gemini Client for Google Gemini Models Source: https://context7.com/clifton/rstructor/llms.txt Connects to Google's Gemini models, with support for thinking levels on Gemini 3 models. Requires the GEMINI_API_KEY environment variable. ```rust use rstructor::{GeminiClient, GeminiModel, Instructor, LLMClient, ThinkingLevel}; use serde::{Deserialize, Serialize}; #[derive(Instructor, Serialize, Deserialize, Debug)] struct Recipe { name: String, ingredients: Vec, instructions: Vec, prep_time_minutes: u16, } #[tokio::main] async fn main() -> Result<(), Box> { // Create client from environment variable GEMINI_API_KEY let client = GeminiClient::from_env()? .model("gemini-2.0-flash") .temperature(0.2) .thinking_level(ThinkingLevel::Low); let recipe: Recipe = client .materialize("Create a simple pasta recipe") .await?; println!("Recipe: {}", recipe.name); println!("Prep time: {} minutes", recipe.prep_time_minutes); for (i, step) in recipe.instructions.iter().enumerate() { println!("{}. {}", i + 1, step); } Ok(()) } ``` -------------------------------- ### Fetching OpenAI Models via cURL Source: https://github.com/clifton/rstructor/blob/main/CLAUDE.md This command fetches the list of available models from the OpenAI API. It requires an API key for authorization and returns a JSON object containing model details. ```bash curl https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY" ``` -------------------------------- ### Configuring LLM Thinking Depth (Rust) Source: https://github.com/clifton/rstructor/blob/main/README.md Shows how to configure the reasoning depth for supported LLM models using the `thinking_level` method. This allows control over the model's cognitive effort, with levels ranging from 'Off' to 'High'. ```rust use rstructor::ThinkingLevel; // Example for GPT-5.2, Claude 4.5 (Sonnet/Opus), Gemini 3 let client = OpenAIClient::from_env()? // Assuming OpenAIClient is used .model("gpt-5.2") .thinking_level(ThinkingLevel::High); // Supported Levels: Off, Minimal, Low, Medium, High ``` -------------------------------- ### Grok Client for xAI Grok Models Source: https://context7.com/clifton/rstructor/llms.txt Connects to xAI's Grok models for chat completions. Requires the XAI_API_KEY environment variable. ```rust use rstructor::{GrokClient, Instructor, LLMClient}; use serde::{Deserialize, Serialize}; #[derive(Instructor, Serialize, Deserialize, Debug)] struct TechExplanation { concept: String, simple_explanation: String, technical_details: String, use_cases: Vec, } #[tokio::main] async fn main() -> Result<(), Box> { // Create client from environment variable XAI_API_KEY let client = GrokClient::from_env()? .model("grok-4-1-fast-non-reasoning") .temperature(0.3); let explanation: TechExplanation = client .materialize("Explain what WebAssembly is") .await?; println!("Concept: {}", explanation.concept); println!("Simple: {}", explanation.simple_explanation); println!("Use cases: {:?}", explanation.use_cases); Ok(()) } ``` -------------------------------- ### Fetching Anthropic Models via cURL Source: https://github.com/clifton/rstructor/blob/main/CLAUDE.md This command retrieves the list of models supported by Anthropic's API. It requires an API key and a specific API version header for authentication and proper request handling. ```bash curl https://api.anthropic.com/v1/models -H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" ``` -------------------------------- ### List Available LLM Models with Rstructor in Rust Source: https://context7.com/clifton/rstructor/llms.txt Demonstrates how to query the Rstructor library to retrieve a list of available models from different LLM providers, specifically OpenAI and Anthropic. This function is useful for dynamically selecting models for API calls. ```rust use rstructor::{LLMClient, OpenAIClient, AnthropicClient}; #[tokio::main] async fn main() -> Result<(), Box> { // List OpenAI models let openai = OpenAIClient::from_env()?; let models = openai.list_models().await?; println!("Available OpenAI models:"); for model in models { println!(" - {}", model.id); } // List Anthropic models let anthropic = AnthropicClient::from_env()?; let models = anthropic.list_models().await?; println!("\nAvailable Anthropic models:"); for model in models { let name = model.name.unwrap_or(model.id.clone()); println!(" - {} ({})", name, model.id); } Ok(()) } ``` -------------------------------- ### Add rstructor to Rust Project Dependencies Source: https://github.com/clifton/rstructor/blob/main/README.md This snippet shows how to add the rstructor crate and its necessary dependencies (serde, tokio) to a Rust project's Cargo.toml file. It specifies the version for rstructor and enables derive features for serde. ```toml [dependencies] rstructor = "0.2" serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.0", features = ["rt-multi-thread", "macros"] } ``` -------------------------------- ### Anthropic Client for Claude Models Source: https://context7.com/clifton/rstructor/llms.txt Connects to Anthropic's Claude models, supporting extended thinking on Claude 4.x. It uses native structured outputs for guaranteed schema compliance. Requires the ANTHROPIC_API_KEY environment variable. ```rust use rstructor::{AnthropicClient, AnthropicModel, Instructor, LLMClient, ThinkingLevel}; use serde::{Deserialize, Serialize}; #[derive(Instructor, Serialize, Deserialize, Debug)] struct CodeReview { issues: Vec, suggestions: Vec, overall_quality: String, } #[tokio::main] async fn main() -> Result<(), Box> { // Create client from environment variable ANTHROPIC_API_KEY let client = AnthropicClient::from_env()? .model(AnthropicModel::ClaudeSonnet45) // Claude Sonnet 4.5 .temperature(0.0) .max_tokens(2048) .thinking_level(ThinkingLevel::Medium); // Enable thinking for Claude 4.x let review: CodeReview = client .materialize("Review this Python code: def add(a, b): return a + b") .await?; println!("Issues: {:?}", review.issues); println!("Suggestions: {:?}", review.suggestions); println!("Quality: {}", review.overall_quality); // Available Claude models: // - ClaudeSonnet45, ClaudeHaiku45 (latest) // - ClaudeOpus41, ClaudeOpus4, ClaudeSonnet4 // - Claude37Sonnet, Claude35Haiku, Claude3Haiku, Claude3Opus Ok(()) } ``` -------------------------------- ### Extracting LLM Response with Metadata (Rust) Source: https://github.com/clifton/rstructor/blob/main/README.md Demonstrates how to materialize an LLM response into a specific struct and access associated metadata, such as token usage. This is useful for monitoring and optimizing LLM interactions. ```rust let result = client.materialize_with_metadata::("...").await?; println!("Movie: {}", result.data.title); if let Some(usage) = result.usage { println!("Tokens: {} in, {} out", usage.input_tokens, usage.output_tokens); } ``` -------------------------------- ### Serde Rename Support in Rstructor (Rust) Source: https://github.com/clifton/rstructor/blob/main/README.md Demonstrates how rstructor respects `#[serde(rename)]` and `#[serde(rename_all)]` attributes for mapping Rust struct fields to JSON keys. This allows for flexible naming conventions in LLM responses. ```rust use rstructor::Instructor; use serde::{Serialize, Deserialize}; #[derive(Instructor, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct UserProfile { first_name: String, // becomes "firstName" in schema last_name: String, // becomes "lastName" in schema email_address: String, // becomes "emailAddress" in schema } #[derive(Instructor, Serialize, Deserialize)] struct CommitMessage { #[serde(rename = "type")] // use "type" as JSON key commit_type: String, description: String, } #[derive(Instructor, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] enum CommitType { Fix, Feat, Refactor, } ``` -------------------------------- ### Rstructor Feature Flags in Cargo.toml (TOML) Source: https://github.com/clifton/rstructor/blob/main/README.md Shows how to configure feature flags for the rstructor dependency in a Cargo.toml file. This allows enabling specific provider backends (e.g., OpenAI, Anthropic) and integrations (e.g., derive, logging). ```toml [dependencies] rstructor = { version = "0.2", features = ["openai", "anthropic", "grok", "gemini"] } # Provider backends: openai, anthropic, grok, gemini # derive — Derive macro (default) # logging — Tracing integration ``` -------------------------------- ### Handle API Errors with Rstructor in Rust Source: https://context7.com/clifton/rstructor/llms.txt Demonstrates how to handle API errors returned by Rstructor, including transient errors, rate limiting, authentication failures, and invalid models. It shows how to check for retryable errors and extract specific error details for user feedback or retry logic. ```rust use rstructor::{ApiErrorKind, Instructor, LLMClient, OpenAIClient, RStructorError}; use serde::{Deserialize, Serialize}; #[derive(Instructor, Serialize, Deserialize)] struct Data { value: String, } #[tokio::main] async fn main() -> Result<(), Box> { let client = OpenAIClient::from_env()?; match client.materialize::("Generate some data").await { Ok(data) => println!("Success: {}", data.value), Err(e) if e.is_retryable() => { println!("Transient error (will retry): {}", e); if let Some(delay) = e.retry_delay() { println!("Suggested wait: {:?}", delay); tokio::time::sleep(delay).await; // Retry the request... } } Err(e) => { // Handle specific error types match e.api_error_kind() { Some(ApiErrorKind::RateLimited { retry_after }) => { println!("Rate limited! Wait {:?}", retry_after); } Some(ApiErrorKind::AuthenticationFailed) => { println!("Check your API key (OPENAI_API_KEY)"); } Some(ApiErrorKind::InvalidModel { model, suggestion }) => { println!("Model '{}' not found", model); if let Some(alt) = suggestion { println!("Try: {}", alt); } } Some(ApiErrorKind::RequestTooLarge) => { println!("Reduce prompt length or max_tokens"); } _ => println!("Error: {}", e), } } } Ok(()) } ``` -------------------------------- ### Custom Type Schema for Dates and UUIDs (Rust) Source: https://github.com/clifton/rstructor/blob/main/README.md Illustrates how to implement the `CustomTypeSchema` trait for custom types like `DateTime` to define their schema representation. This is useful for types that have specific JSON schema formats, such as 'date-time'. ```rust use chrono::{DateTime, Utc}; use rstructor::schema::CustomTypeSchema; impl CustomTypeSchema for DateTime { fn schema_type() -> &'static str { "string" } fn schema_format() -> Option<&'static str> { Some("date-time") } } #[derive(Instructor, Serialize, Deserialize)] struct Event { name: String, start_time: DateTime, } ``` -------------------------------- ### Rust: Define Nested Structures with Rstructor Source: https://context7.com/clifton/rstructor/llms.txt This code snippet demonstrates how to define complex, nested data structures in Rust using Rstructor. It showcases nested structs (`Ingredient`, `Step`, `Nutrition`) and vectors of structs (`Vec`, `Vec`) within a main `Recipe` struct. This allows for the representation of hierarchical data, such as a recipe with its ingredients, preparation steps, and nutritional information. ```rust use rstructor::{Instructor, LLMClient, OpenAIClient}; use serde::{Deserialize, Serialize}; #[derive(Instructor, Serialize, Deserialize, Debug)] struct Ingredient { #[llm(description = "Ingredient name", example = "flour")] name: String, #[llm(description = "Amount needed", example = 2.5)] amount: f32, #[llm(description = "Unit of measurement", example = "cups")] unit: String, } #[derive(Instructor, Serialize, Deserialize, Debug)] struct Step { #[llm(description = "Step number", example = 1)] number: u16, #[llm(description = "Step instructions")] description: String, #[llm(description = "Time in minutes")] time_minutes: Option, } #[derive(Instructor, Serialize, Deserialize, Debug)] struct Nutrition { calories: u16, protein_g: f32, carbs_g: f32, fat_g: f32, } #[derive(Instructor, Serialize, Deserialize, Debug)] struct Recipe { name: String, description: String, prep_time_minutes: u16, cook_time_minutes: u16, servings: u8, ingredients: Vec, steps: Vec, nutrition: Nutrition, } #[tokio::main] async fn main() -> Result<(), Box> { let client = OpenAIClient::from_env()?; let recipe: Recipe = client .materialize("Create a recipe for chocolate chip cookies") .await?; println!("Recipe: {}", recipe.name); println!("Prep: {} min, Cook: {} min", recipe.prep_time_minutes, recipe.cook_time_minutes); println!("\nIngredients:"); for ing in &recipe.ingredients { println!(" {} {} {}", ing.amount, ing.unit, ing.name); } println!("\nSteps:"); for step in &recipe.steps { println!(" {}. {}", step.number, step.description); } println!("\nNutrition per serving:"); println!(" {} cal, {}g protein, {}g carbs, {}g fat", recipe.nutrition.calories, recipe.nutrition.protein_g, recipe.nutrition.carbs_g, recipe.nutrition.fat_g); Ok(()) } ``` -------------------------------- ### Define Nested Structures for Complex Data with rstructor Source: https://github.com/clifton/rstructor/blob/main/README.md This snippet demonstrates how to define nested data structures using Rust structs for use with rstructor. It shows a 'Recipe' struct containing a vector of 'Ingredient' structs, illustrating how rstructor handles complex, hierarchical data models. ```rust #[derive(Instructor, Serialize, Deserialize)] struct Ingredient { name: String, amount: f32, unit: String, } #[derive(Instructor, Serialize, Deserialize)] struct Recipe { name: String, ingredients: Vec, prep_time_minutes: u16, } ``` -------------------------------- ### Enums with Associated Data in Rust Source: https://context7.com/clifton/rstructor/llms.txt Demonstrates defining Rust enums with various forms of associated data, enabling discriminated union types. This functionality is useful for representing complex states or options within a program. The `Instructor` derive macro from Rstructor is used for serialization and deserialization. ```rust use rstructor::{Instructor, LLMClient, OpenAIClient}; use serde::{Deserialize, Serialize}; #[derive(Instructor, Serialize, Deserialize, Debug)] enum PaymentMethod { #[llm(description = "Credit card payment")] Card { number: String, expiry: String, cvv: String }, #[llm(description = "PayPal account email")] PayPal(String), #[llm(description = "Bank transfer")] BankTransfer { account: String, routing: String }, #[llm(description = "Cash payment")] Cash, } #[derive(Instructor, Serialize, Deserialize, Debug)] enum TaskStatus { #[llm(description = "Task not started")] Pending, #[llm(description = "Task in progress with completion percentage")] InProgress(u8), #[llm(description = "Task completed")] Completed, #[llm(description = "Task failed with error message")] Failed(String), } #[derive(Instructor, Serialize, Deserialize, Debug)] struct Order { order_id: String, total: f64, payment: PaymentMethod, status: TaskStatus, } #[tokio::main] async fn main() -> Result<(), Box> { let client = OpenAIClient::from_env()?; let order: Order = client .materialize("Create a sample order for a $99.99 purchase paid with PayPal") .await?; println!("Order ID: {}", order.order_id); println!("Total: ${:.2}", order.total); println!("Payment: {:?}", order.payment); println!("Status: {:?}", order.status); Ok(()) } ``` -------------------------------- ### Implement Custom JSON Schemas with Rstructor in Rust Source: https://context7.com/clifton/rstructor/llms.txt Shows how to implement the `CustomTypeSchema` trait for custom data types, such as `chrono::DateTime`, to define their JSON schema representations. This allows Rstructor to correctly generate schemas for complex types used in LLM interactions. ```rust use chrono::{DateTime, Utc}; use rstructor::{Instructor, LLMClient, OpenAIClient}; use rstructor::schema::CustomTypeSchema; use serde::{Deserialize, Serialize}; // Implement CustomTypeSchema for chrono's DateTime impl CustomTypeSchema for DateTime { fn schema_type() -> &'static str { "string" } fn schema_format() -> Option<&'static str> { Some("date-time") } fn schema_description() -> Option { Some("ISO-8601 formatted date and time".to_string()) } } #[derive(Instructor, Serialize, Deserialize, Debug)] struct Event { #[llm(description = "Event name")] name: String, #[llm(description = "Event start time in ISO-8601 format")] start_time: DateTime, #[llm(description = "Event end time in ISO-8601 format")] end_time: DateTime, #[llm(description = "Event location")] location: String, } #[tokio::main] async fn main() -> Result<(), Box> { let client = OpenAIClient::from_env()?; let event: Event = client .materialize("Create a tech conference event for next month") .await?; println!("Event: {}", event.name); println!("Start: {}", event.start_time); println!("End: {}", event.end_time); println!("Location: {}", event.location); Ok(()) } ``` -------------------------------- ### Use Enums with Associated Data in rstructor Models Source: https://github.com/clifton/rstructor/blob/main/README.md Illustrates defining Rust enums with associated data as models for rstructor. The 'PaymentMethod' enum shows variants like 'Card' with named fields, 'PayPal' with a single value, and 'CashOnDelivery', all usable with LLM data extraction and validation. ```rust #[derive(Instructor, Serialize, Deserialize)] enum PaymentMethod { #[llm(description = "Credit card payment")] Card { number: String, expiry: String }, #[llm(description = "PayPal account")] PayPal(String), #[llm(description = "Cash on delivery")] CashOnDelivery, } ``` -------------------------------- ### Filtering Gemini Chat Models Source: https://github.com/clifton/rstructor/blob/main/CLAUDE.md This Python function filters Gemini models based on their `supportedGenerationMethods`. It includes models that have 'generateContent' listed in this array. ```python import json def filter_gemini_chat_models(response_json): data = json.loads(response_json) chat_models = [] for model in data.get('models', []): if 'generateContent' in model.get('supportedGenerationMethods', []): chat_models.append(model['name'].replace('models/', '')) return chat_models response_data = '{"models": [{"name": "models/gemini-1.5-flash", "supportedGenerationMethods": ["generateContent"]}, {"name": "models/embedding-001", "supportedGenerationMethods": ["embedContent"]}]}' filtered_models = filter_gemini_chat_models(response_data) print(filtered_models) ``` -------------------------------- ### Parsing Anthropic Model IDs Source: https://github.com/clifton/rstructor/blob/main/CLAUDE.md This Python snippet demonstrates extracting model identifiers from the Anthropic API response. It accesses the 'id' field for each model listed in the response. ```python import json response_json = '{"models": [{"id": "claude-sonnet-4-20250514", ...}, {"id": "claude-3-opus-20240229", ...}]}' data = json.loads(response_json) model_ids = [model['id'] for model in data.get('models', [])] print(model_ids) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.