| Crates.io | hedl |
| lib.rs | hedl |
| version | 1.2.0 |
| created_at | 2026-01-09 00:58:58.186165+00 |
| updated_at | 2026-01-21 03:05:44.951064+00 |
| description | HEDL - Hierarchical Entity Data Language |
| homepage | https://dweve.com |
| repository | https://github.com/dweve/hedl |
| max_upload_size | |
| id | 2031358 |
| size | 212,785 |
The unified HEDL API—parse, validate, convert, and canonicalize with a single, ergonomic interface.
Production systems need simple APIs. Importing a dozen crates for basic operations creates cognitive overhead. Feature flags should work intuitively. Errors need rich context without boilerplate. The most common operations should be frictionless.
hedl is the facade crate providing the complete HEDL experience through 7 core functions and comprehensive error handling utilities. Zero default dependencies—only pay for features you enable. Full re-exports from 13 specialized crates beneath a unified API. Designed for developers who want results, not dependency management.
Unified API with zero-overhead ergonomics:
Parse, validate, and work with HEDL documents:
[dependencies]
hedl = "1.2"
What you get: Parsing, canonicalization, linting, validation What you don't get: Format conversion (JSON/YAML/XML/etc.)
Enable only the formats you need:
[dependencies]
hedl = { version = "1.2", features = ["yaml", "xml"] }
Get everything (recommended for applications):
[dependencies]
hedl = { version = "1.2", features = ["all-formats"] }
Includes: JSON, YAML, XML, CSV, Parquet, Neo4j, TOON, Serde
Parse HEDL document with strict validation:
use hedl::parse;
let hedl = br#"
%VERSION: 1.0
%STRUCT: User: [id, name, age]
---
users: @User
| alice, Alice Smith, 30
| bob, Bob Jones, 25
"#;
let doc = parse(hedl)?;
println!("Version: {}.{}", doc.version.0, doc.version.1);
println!("Users: {}", doc.entities["User"].len());
Behavior:
Use When: Production parsing, CI/CD validation, strict correctness required
Parse with relaxed validation:
let doc = parse_lenient(hedl_bytes)?;
// Tolerates some malformations:
// - Missing schemas (inferred from data)
// - Unresolved references (preserved as strings)
// - Inconsistent indentation (best-effort parse)
Use When: Parsing user-generated content, migration from other formats, exploratory analysis
Validate document without constructing AST:
use hedl::validate;
if validate(hedl_bytes).is_ok() {
println!("Valid HEDL document");
}
Performance: Faster than parse() when you only need validation (no AST construction)
Use Cases: CI/CD checks, pre-commit hooks, batch validation
Convert to canonical form with ditto optimization:
use hedl::{parse, canonicalize};
let doc = parse(hedl_bytes)?;
let canonical = canonicalize(&doc)?;
// Same document always produces identical output
// Perfect for version control and content-addressable storage
Output Characteristics:
Use When: Git commits, content hashing, cache keys, comparing documents
Run lint checks for best practices:
use hedl::{parse, lint};
let doc = parse(hedl_bytes)?;
let diagnostics = lint(&doc);
for diag in diagnostics {
println!("[{}] Line {}: {}",
diag.severity, diag.line, diag.message);
}
Rules Checked (default):
Use When: Code review automation, CI/CD quality gates, pre-commit hooks
Convert to JSON (requires "json" feature, enabled by default):
use hedl::{parse, to_json};
let doc = parse(hedl_bytes)?;
let json = to_json(&doc)?;
// Use with existing JSON APIs
Configuration: Use hedl_json::to_json_with_config() for custom options (pretty-printing, type preservation)
Convert from JSON to HEDL:
use hedl::from_json;
let json = r#"{"users": [{"id": "alice", "name": "Alice"}]}"#;
let doc = from_json(json)?;
// Now use HEDL's structured API
Type Inference: Automatically detects arrays-of-objects → matrix lists
Standard Rust errors lose context during propagation:
fn load_config() -> Result<Config> {
let data = std::fs::read("config.hedl")?;
let doc = parse(&data)?;
// Error: "Parse error at line 42: unexpected token"
// Missing: WHICH file? WHAT operation?
}
Add context at error boundaries:
use hedl::{parse, HedlResultExt};
fn load_config(path: &str) -> Result<Config> {
let data = std::fs::read(path)
.context("Failed to read config file")?;
let doc = parse(&data)
.with_context(|| format!("Failed to parse config: {}", path))?;
Ok(/* ... */)
}
Output:
Failed to parse config: config.hedl
caused by: Parse error at line 42: unexpected token ':'
Add static context:
parse(data).context("Failed to parse HEDL document")?;
Add computed context (lazily evaluated):
parse(data)
.with_context(|| format!("Failed to parse file: {}", filename))?;
Benefits:
Convert external errors to HedlError:
std::fs::read("file.hedl")
.map_err_to_hedl()
.context("Failed to read input")?;
Use Cases:
Enable Serde serialization for Document type:
hedl = { version = "1.2", features = ["serde"] }
Provides: Serialize/Deserialize impls for Document, Value, Reference
Use Cases: Storing parsed documents in databases, IPC, caching
Enable YAML format conversion:
hedl = { version = "1.2", features = ["yaml"] }
Adds:
hedl::to_yaml(doc) -> Result<String>hedl::from_yaml(yaml) -> Result<Document>Dependencies: serde_yaml 0.9
Enable XML format conversion:
hedl = { version = "1.2", features = ["xml"] }
Adds:
hedl::to_xml(doc) -> Result<String>hedl::from_xml(xml) -> Result<Document>Dependencies: quick-xml 0.31
Enable CSV format conversion:
hedl = { version = "1.2", features = ["csv"] }
Adds:
hedl::to_csv(doc) -> Result<String> (exports first entity list)hedl::from_csv(csv, type_name) -> Result<Document>Dependencies: csv 1.3
Enable Apache Parquet columnar format:
hedl = { version = "1.2", features = ["parquet"] }
Adds:
hedl::to_parquet(doc, writer) -> Result<()>hedl::from_parquet(reader) -> Result<Document>Dependencies: arrow 57.0, parquet 57.0
Enable Neo4j Cypher generation:
hedl = { version = "1.2", features = ["neo4j"] }
Adds:
hedl::to_cypher(doc) -> Result<String>Dependencies: None (pure Cypher generation)
Enable TOON format (token-optimized for LLMs):
hedl = { version = "1.2", features = ["toon"] }
Adds:
hedl::to_toon(doc) -> Result<String>hedl::from_toon(toon) -> Result<Document>Use Case: Maximum token efficiency for LLM contexts
Enable all format converters:
hedl = { version = "1.2", features = ["all-formats"] }
Equivalent to: ["serde", "yaml", "xml", "csv", "parquet", "neo4j", "toon"]
Recommended for: Applications (not libraries)
Full access to specialized crates through unified namespace:
use hedl::{
// Core types
Document, Value, Reference, HedlError,
// Sub-modules (explicit opt-in)
core, // hedl-core (parsing, AST)
c14n, // hedl-c14n (canonicalization)
json, // hedl-json (always available)
lint, // hedl-lint (linting)
// Feature-gated modules
yaml, // hedl-yaml (requires "yaml")
xml, // hedl-xml (requires "xml")
csv, // hedl-csv (requires "csv")
parquet, // hedl-parquet (requires "parquet")
neo4j, // hedl-neo4j (requires "neo4j")
toon, // hedl-toon (requires "toon")
};
Use When: Need advanced configuration beyond core API (e.g., hedl::json::JsonConfig for custom JSON options)
use hedl::{parse, to_json};
let doc = parse(hedl_bytes)?;
let json = to_json(&doc)?;
// Send JSON to REST API
use hedl::{validate, parse};
if validate(hedl_bytes).is_err() {
return Err("Invalid HEDL document");
}
let doc = parse(hedl_bytes)?; // Safe to unwrap
use hedl::{from_json, to_yaml, to_xml};
let doc = from_json(json_str)?;
let yaml = to_yaml(&doc)?;
let xml = to_xml(&doc)?;
use hedl::{parse, HedlResultExt};
fn process_file(path: &str) -> Result<()> {
let data = std::fs::read(path)
.context("Failed to read input file")?;
let doc = parse(&data)
.with_context(|| format!("Failed to parse: {}", path))?;
let canonical = canonicalize(&doc)
.context("Failed to canonicalize document")?;
std::fs::write(format!("{}.canonical", path), canonical)
.context("Failed to write canonical output")?;
Ok(())
}
Convenient Result type with HedlError:
pub type Result<T> = std::result::Result<T, HedlError>;
// Use in function signatures
fn my_function() -> Result<Document> {
parse(input)?
}
Zero Overhead: Facade adds < 1% overhead vs using crates directly
Feature Gating: Unused features don't bloat binary (tree-shaking works)
Compile Time: Minimal—most work delegated to specialized crates
Binary Size: Core-only build ~200 KB, all-formats ~800 KB (compressed)
Application Development: Use features = ["all-formats"] for maximum flexibility without managing individual crate versions.
Library Development: Minimize dependencies—only enable formats your library needs. Let downstream users add more formats via their own dependencies.
CLI Tools: Import hedl with all-formats for comprehensive format support in user-facing tools.
Embedded Systems: Use core-only (no features) for minimal binary size. Add formats selectively based on constraints.
Microservices: Enable only formats you consume/produce (e.g., JSON for REST APIs, Parquet for analytics export).
Streaming Parsing: Use hedl-stream directly for memory-efficient streaming of multi-GB files.
LSP/MCP Servers: Use hedl-lsp or hedl-mcp directly for server applications.
C/WASM Bindings: Use hedl-ffi or hedl-wasm directly for non-Rust integrations.
Benchmarking: Use hedl-bench directly for performance measurement and regression detection.
Testing Utilities: Use hedl-test directly for shared test fixtures and builders.
hedl-core 1.0 - Parsing and ASThedl-c14n 1.0 - Canonicalizationhedl-json 1.0 - JSON (always included)hedl-lint 1.0 - Lintingthiserror 1.0 - Error typeshedl-yaml 1.0 - YAML conversion (feature: yaml)hedl-xml 1.0 - XML conversion (feature: xml)hedl-csv 1.0 - CSV conversion (feature: csv)hedl-parquet 1.0 - Parquet conversion (feature: parquet)hedl-neo4j 1.0 - Neo4j Cypher (feature: neo4j)hedl-toon 1.0 - TOON format (feature: toon)serde 1.0 - Serialization (feature: serde)Apache-2.0