| Crates.io | rust-yaml |
| lib.rs | rust-yaml |
| version | 0.0.5 |
| created_at | 2025-08-19 00:19:09.718791+00 |
| updated_at | 2025-08-20 19:57:37.125165+00 |
| description | A fast, safe YAML 1.2 library for Rust |
| homepage | |
| repository | https://github.com/elioetibr/rust-yaml |
| max_upload_size | |
| id | 1801251 |
| size | 862,316 |
A complete, fast, and safe YAML 1.2 library for Rust with advanced features and security-first design. This library provides comprehensive YAML processing capabilities with full specification compliance, advanced security features, and excellent performance.
Status: Production-ready with comprehensive test coverage (134 unit tests + 150+ integration tests passing). All YAML 1.2 core features implemented and battle-tested.
rust-yaml stands out from other YAML libraries by providing:
&anchor and *alias references|) and folded (>) block scalars!!str, !!int, !!map, !!seq)Add this to your Cargo.toml:
[dependencies]
rust-yaml = "0.0.5"
use rust_yaml::Yaml;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let yaml = Yaml::new();
// Parse YAML from a string
let yaml_content = r#"
name: "rust-yaml"
version: "0.0.5"
features:
- fast
- safe
- reliable
config:
debug: true
max_depth: 100
"#;
let parsed = yaml.load_str(yaml_content)?;
println!("Parsed: {:#?}", parsed);
// Dump back to YAML
let output = yaml.dump_str(&parsed)?;
println!("Output:\n{}", output);
Ok(())
}
use rust_yaml::Yaml;
let yaml = Yaml::new();
let multi_doc = r#"
document: 1
data: [1, 2, 3]
---
document: 2
data: [4, 5, 6]
---
document: 3
data: [7, 8, 9]
"#;
let documents = yaml.load_all_str(multi_doc)?;
println!("Found {} documents", documents.len());
use rust_yaml::{Yaml, YamlConfig, LoaderType};
let config = YamlConfig {
loader_type: LoaderType::Safe,
allow_duplicate_keys: false,
explicit_start: Some(true),
width: Some(120),
..Default::default()
};
let yaml = Yaml::with_config(config);
use rust_yaml::Yaml;
let yaml = Yaml::new();
let yaml_with_anchors = r#"
defaults: &defaults
timeout: 30
retries: 3
development:
<<: *defaults
debug: true
production:
<<: *defaults
debug: false
"#;
let parsed = yaml.load_str(yaml_with_anchors)?;
let yaml_with_multiline = r#"
# Literal block scalar (preserves newlines)
sql_query: |
SELECT name, age
FROM users
WHERE active = true
ORDER BY name;
# Folded block scalar (folds newlines to spaces)
description: >
This is a long description that will be
folded into a single line when parsed,
making it easier to read in the YAML file.
"#;
let parsed = yaml.load_str(yaml_with_multiline)?;
let yaml_with_tags = r#"
string_value: !!str 42 # Force as string
int_value: !!int "123" # Force as integer
float_value: !!float "3.14" # Force as float
bool_value: !!bool "yes" # Force as boolean
sequence: !!seq [a, b, c] # Explicit sequence
mapping: !!map {key: value} # Explicit mapping
"#;
let parsed = yaml.load_str(yaml_with_tags)?;
// YAML 1.2 supports using complex structures as mapping keys
let yaml_with_complex_keys = r#"
# Sequence as a key
? [name, age]
: [John, 30]
# Mapping as a key
? {first: Alice, last: Smith}
: person_data
# Mixed with regular keys
simple_key: simple_value
? [complex, sequence, key]
: complex_value
"#;
let parsed = yaml.load_str(yaml_with_complex_keys)?;
// The parser correctly handles complex keys and can round-trip them
let serialized = yaml.dump_str(&parsed)?;
use rust_yaml::Yaml;
// Load application configuration with anchors for shared settings
let config_yaml = r#"
defaults: &defaults
timeout: 30
retry_count: 3
log_level: info
database:
<<: *defaults
host: localhost
port: 5432
api:
<<: *defaults
host: 0.0.0.0
port: 8080
cors_enabled: true
"#;
let config = yaml.load_str(config_yaml)?;
// Process data with explicit types to ensure correctness
let data_yaml = r#"
users:
- id: !!int "1001"
name: !!str "Alice"
active: !!bool "yes"
score: !!float "95.5"
- id: !!int "1002"
name: !!str "Bob"
active: !!bool "no"
score: !!float "87.2"
"#;
let users = yaml.load_str(data_yaml)?;
use rust_yaml::{Yaml, Value};
use indexmap::IndexMap;
// Create shared data structure
let shared_config = {
let mut map = IndexMap::new();
map.insert(Value::String("timeout".to_string()), Value::Int(30));
map.insert(Value::String("retries".to_string()), Value::Int(3));
Value::Mapping(map)
};
// Use it multiple times - rust-yaml will automatically create anchors/aliases
let mut root = IndexMap::new();
root.insert(Value::String("dev".to_string()), shared_config.clone());
root.insert(Value::String("prod".to_string()), shared_config.clone());
let output = yaml.dump_str(&Value::Mapping(root))?;
// Output will contain: dev: &anchor0 ... prod: *anchor0
The library provides a comprehensive Value enum for representing YAML data:
use rust_yaml::Value;
let values = vec![
Value::Null,
Value::Bool(true),
Value::Int(42),
Value::Float(3.14),
Value::String("hello".to_string()),
Value::Sequence(vec![Value::Int(1), Value::Int(2)]),
Value::mapping(), // Empty mapping
];
Advanced error reporting with precise position information and visual context:
use rust_yaml::{Yaml, Error};
let yaml = Yaml::new();
let result = yaml.load_str("invalid: yaml: content:");
match result {
Ok(value) => println!("Success: {:?}", value),
Err(Error::Parse { position, message, context }) => {
println!("Parse error at line {}, column {}: {}",
position.line, position.column, message);
// Enhanced error context with visual indicators
if let Some(ctx) = context {
println!("Context:\n{}", ctx.line_content);
println!("{}^", " ".repeat(ctx.column_position));
if let Some(suggestion) = &ctx.suggestion {
println!("Suggestion: {}", suggestion);
}
}
}
Err(e) => println!("Other error: {}", e),
}
Different loader types provide varying levels of functionality and security:
Safe (default): Only basic YAML types, no code executionBase: Minimal type set for simple use casesRoundTrip: Preserves formatting and comments (partial implementation available)Full: All features including potentially unsafe operationsrust-yaml is designed for high performance:
IndexMap for preserving key order
# Run performance benchmarks
cargo bench
# Run with release optimizations
cargo test --release
# Profile memory usage
cargo test --features large-documents
[dependencies]
rust-yaml = { version = "0.0.5", features = ["serde", "large-documents"] }
default = ["mmap", "preserve-order"]: Default feature set with memory mapping and order preservationserde: Enable serde serialization support for Rust structspreserve-order: Always preserve key insertion order (uses IndexMap)large-documents: Optimizations for very large YAML documentsasync: Async/await support with tokio integrationmmap: Memory-mapped file support for large documentsfull: All features enabledParsing & Generation
---References & Inheritance
&anchor, *alias) with proper nested mapping support<<) - Complete inheritance support with override behaviorText Processing
|) and folded (>) block scalarsType System
!!str, !!int, !!map, !!seq) with normalizationEnterprise Features
Full Round-trip Comment Preservation
load_str_with_comments(), dump_str_with_comments()// Full comment preservation example
let config = YamlConfig {
preserve_comments: true,
loader_type: LoaderType::RoundTrip,
..Default::default()
};
let yaml = Yaml::with_config(config);
// Parse with full comment preservation
let commented_value = yaml.load_str_with_comments(yaml_with_comments)?;
// Serialize back with comments intact
let output = yaml.dump_str_with_comments(&commented_value)?;
// Output includes all original comments in appropriate positions
Enterprise-Grade Validation System
use rust_yaml::{Yaml, Schema, SchemaRule, ValueType};
use regex::Regex;
use std::collections::HashMap;
// Create comprehensive schema
let mut properties = HashMap::new();
properties.insert("name".to_string(),
Schema::with_type(ValueType::String)
.rule(SchemaRule::Length { min: Some(1), max: Some(100) }));
properties.insert("email".to_string(),
Schema::with_type(ValueType::String)
.rule(SchemaRule::Pattern(Regex::new(r"^[^@]+@[^@]+\.[^@]+$").unwrap())));
properties.insert("age".to_string(),
Schema::with_type(ValueType::Integer)
.rule(SchemaRule::Range { min: Some(0.0), max: Some(150.0) }));
let schema = Schema::with_type(ValueType::Object)
.rule(SchemaRule::Properties(properties))
.rule(SchemaRule::Required(vec!["name".to_string(), "email".to_string()]))
.info("User Schema", "Validates user information");
let yaml = Yaml::new();
// Load and validate in one step
let user_data = yaml.load_str_with_schema(r#"
name: "Alice Johnson"
email: "alice@example.com"
age: 30
"#, &schema)?;
// Or validate existing data
let parsed_data = yaml.load_str("name: Bob")?;
yaml.validate_with_schema(&parsed_data, &schema)?; // Will fail - missing email
Enterprise Features
Performance & Developer Tools
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
# Clone the repository
git clone https://github.com/elioetibr/rust-yaml.git
cd rust-yaml
# Set up development environment (git hooks, components, etc.)
make setup
# Run all tests
make test
# Run CI pipeline locally (same as GitHub Actions)
make ci
# Quick development checks (format, lint, test)
make quick-check
The project includes a comprehensive Makefile with 60+ commands for development workflow:
Testing
make test # Run all tests
make test-lib # Run library tests only
make test-integration # Run integration tests
make test-security # Run security-specific tests
make test-release # Run tests in release mode
Code Quality
make format # Format code with rustfmt
make lint # Run clippy lints
make clippy-strict # Run strict clippy with CI settings
make audit # Run security audit
make deny # Run cargo deny checks
Documentation & Reports
make doc # Build documentation
make doc-open # Build and open documentation
make bench # Run performance benchmarks
Coverage Reports
make coverage # Generate test coverage report (CI-compatible)
make coverage-html # Generate HTML coverage report
make coverage-view # Generate and open HTML coverage in browser
make coverage-clean # Clean coverage artifacts
make coverage-install-tools # Install coverage tools
# Alternative coverage tools
make coverage-llvm # Generate coverage using llvm-cov
make coverage-llvm-html # Generate HTML coverage with llvm-cov
CI/CD & Checks
make ci # Full CI pipeline (format, lint, test, security)
make check # Basic checks (build, test, format, lint)
make check-all # Comprehensive checks with audit and coverage
make release-check # Check if ready for release
Markdown & Documentation
make check-markdown # Check markdown formatting issues
make fix-markdown # Fix common markdown formatting issues
make help # Show all available commands
The project includes comprehensive documentation in the docs/ directory:
Core Documentation
Feature Documentation
<<)%YAML, %TAG) supportPerformance & Analysis
Development Tools
Project Files
This project is licensed under the MIT License - see the LICENSE file for details.
indexmap and thiserror