Skip to content

huml-lang/huml-rs

Repository files navigation

HUML Parser for Rust

This is a Rust library for the HUML (Human-Usable Markup Language) data serialization format.

Features

  • Serde Support: Full bidirectional support - serialize Rust structs to HUML and deserialize HUML into Rust structs.
  • Full compliant with HUML specification
    • Supports all HUML data types (string, number, boolean, array, object)
    • Handles comments and whitespace correctly

Usage

Add this to your Cargo.toml:

[dependencies]
huml-rs = "0.1.0" # Replace with the desired version
serde = { version = "1.0", features = ["derive"] }

Low-level Parsing

Then, you can parse a HUML string like this:

use huml_rs::parse_huml;

fn main() {
    let huml_string = r#"
%HUML v0.1.0

app_name: "My Awesome App"
version: "1.0"
debug_mode: true
    "#;

    match parse_huml(huml_string) {
        Ok((remaining, document)) => {
            if !remaining.trim().is_empty() {
                eprintln!("Warning: Unparsed input remains: {}", remaining);
            }
            println!("Successfully parsed HUML document!");
            println!("Version: {:?}", document.version);
            println!("Root value: {:?}", document.root);
        }
        Err(e) => {
            eprintln!("Failed to parse HUML: {:?}", e);
        }
    }
}

Serde Integration (Serialization & Deserialization)

HUML-rs provides full bidirectional serde support for seamless integration with Rust structs.

Deserializing HUML into Rust Structs

use huml_rs::serde::from_str;
use serde::Deserialize;

#[derive(Deserialize, Debug)]
struct Config {
    app_name: String,
    port: u16,
    debug_mode: bool,
    features: Vec<String>,
    database: DatabaseConfig,
}

#[derive(Deserialize, Debug)]
struct DatabaseConfig {
    host: String,
    port: u16,
    ssl: bool,
}

fn main() {
    let huml_string = r#"
app_name: "My Awesome App"
port: 8080
debug_mode: true
features:: "auth", "logging", "metrics"
database::
  host: "localhost"
  port: 5432
  ssl: true
    "#;

    match from_str::<Config>(huml_string) {
        Ok(config) => {
            println!("Successfully deserialized config: {:#?}", config);
        }
        Err(e) => {
            eprintln!("Failed to deserialize HUML: {}", e);
        }
    }
}

Serializing Rust Structs to HUML

use huml_rs::serde::to_string;
use serde::Serialize;

#[derive(Serialize)]
struct Config {
    app_name: String,
    port: u16,
    debug_mode: bool,
    features: Vec<String>,
    database: DatabaseConfig,
}

#[derive(Serialize)]
struct DatabaseConfig {
    host: String,
    port: u16,
    ssl: bool,
}

fn main() {
    let config = Config {
        app_name: "My Awesome App".to_string(),
        port: 8080,
        debug_mode: true,
        features: vec!["auth".to_string(), "logging".to_string(), "metrics".to_string()],
        database: DatabaseConfig {
            host: "localhost".to_string(),
            port: 5432,
            ssl: true,
        },
    };

    match to_string(&config) {
        Ok(huml) => {
            println!("Serialized HUML:\n{}", huml);
            // Output:
            // app_name: "My Awesome App"
            // port: 8080
            // debug_mode: true
            // features:: "auth", "logging", "metrics"
            // database::
            //   host: "localhost"
            //   port: 5432
            //   ssl: true
        }
        Err(e) => {
            eprintln!("Failed to serialize to HUML: {}", e);
        }
    }
}

Round-trip Serialization

HUML maintains perfect round-trip fidelity:

use huml_rs::serde::{to_string, from_str};
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Data {
    name: String,
    values: Vec<i32>,
}

let original = Data {
    name: "test".to_string(),
    values: vec![1, 2, 3],
};

// Serialize to HUML
let huml = to_string(&original).unwrap();

// Deserialize back to struct
let restored: Data = from_str(&huml).unwrap();

assert_eq!(original, restored); // Perfect round-trip!

Development

This project is built with Rust and nom.

To build the project:

cargo build

To run tests:

cargo test

Standard HUML Test Suite

This parser includes the official HUML test suite as a git submodule, which contains centrally maintained test cases that all HUML parser implementations should pass. These tests help ensure compatibility and correctness across different parsers.

To initialize the test submodule:

git submodule init
git submodule update

The standard tests include:

  • Assertion Tests: 174+ test cases covering valid and invalid HUML syntax
  • Document Tests: Complete HUML documents with expected JSON output for validation

To run only the standard tests:

cargo test standard_tests

Current Status:

  • ✅ Document parsing test passes (with acceptable multiline string differences)
  • ✅ All assertion tests pass.

To run benchmarks:

cargo bench

Benchmarking

This project includes comprehensive benchmarks using Criterion.rs to measure parsing performance across different scenarios:

Benchmark Categories

  • Full Document Parsing: Measures performance parsing the complete test.huml file
  • Component Parsing: Tests individual parsing functions (strings, numbers, booleans, etc.)
  • Collection Parsing: Benchmarks inline and multiline lists/dictionaries
  • Multiline Strings: Tests both preserved and stripped formatting
  • Document Sizes: Compares performance across small, medium, and large documents
  • Edge Cases: Tests long strings, deep nesting, and large collections
  • Memory Usage: Measures allocation patterns and repeated parsing

Running Benchmarks

# Run all benchmarks
cargo bench

# Run specific benchmark group
cargo bench parse_components

# Generate HTML reports (requires criterion html_reports feature)
cargo bench --features html_reports

Contributing

Contributions are welcome! Please feel free to open an issue or submit a pull request.

About

Rust library for parsing Human-oriented Markup Language(HUML) http://huml.io

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published