| Crates.io | links-notation |
| lib.rs | links-notation |
| version | 0.13.0 |
| created_at | 2025-10-12 08:56:30.405831+00 |
| updated_at | 2025-12-01 20:26:02.002262+00 |
| description | Rust implementation of the Links Notation parser |
| homepage | |
| repository | https://github.com/link-foundation/links-notation |
| max_upload_size | |
| id | 1879076 |
| size | 151,244 |
Rust implementation of the Links Notation parser using nom parser combinator library.
Add this to your Cargo.toml:
[dependencies]
links-notation = { path = "." } # For local development
# Or from a registry:
# links-notation = "0.9.0"
Clone the repository and build:
git clone https://github.com/link-foundation/links-notation.git
cd links-notation/rust
cargo build
Build the project:
cargo build
Build with optimizations:
cargo build --release
Run tests:
cargo test
Run tests with output:
cargo test -- --nocapture
use links_notation::{parse_lino, LiNo};
fn main() {
// Parse Links Notation format string
let input = r#"papa (lovesMama: loves mama)
son lovesMama
daughter lovesMama
all (love mama)"#;
match parse_lino(input) {
Ok(parsed) => {
println!("Parsed: {}", parsed);
// Access the structure
if let LiNo::Link { values, .. } = parsed {
for link in values {
println!("Link: {}", link);
}
}
}
Err(e) => eprintln!("Parse error: {}", e),
}
}
use links_notation::LiNo;
// Create links programmatically
let reference = LiNo::Ref("some_value".to_string());
let link = LiNo::Link {
id: Some("parent".to_string()),
values: vec![
LiNo::Ref("child1".to_string()),
LiNo::Ref("child2".to_string()),
],
};
// Check link types
if link.is_link() {
println!("This is a link");
}
if reference.is_ref() {
println!("This is a reference");
}
use links_notation::parse_lino;
let input = "(parent: child1 child2)";
let parsed = parse_lino(input).unwrap();
// Regular formatting (parenthesized)
println!("Regular: {}", parsed);
// Alternate formatting (line-based)
println!("Alternate: {:#}", parsed);
use links_notation::parse_lino;
// Single line format
let single_line = "id: value1 value2";
let parsed = parse_lino(single_line)?;
// Parenthesized format
let parenthesized = "(id: value1 value2)";
let parsed = parse_lino(parenthesized)?;
// Multi-line with indentation
let indented = r#"parent
child1
child2"#;
let parsed = parse_lino(indented)?;
// Quoted identifiers and values
let quoted = r#"("quoted id": "value with spaces")"#;
let parsed = parse_lino(quoted)?;
papa (lovesMama: loves mama)
son lovesMama
daughter lovesMama
all (love mama)
papa has car
mama has house
(papa and mama) are happy
(linksNotation: links notation)
(This is a linksNotation as well)
(linksNotation supports (unlimited number (of references) in each link))
parent
child1
child2
grandchild1
grandchild2
LiNo<T>Represents either a Link or a Reference:
Link { id: Option<T>, values: Vec<Self> } - A link with optional ID and
child valuesRef(T) - A reference to another linkLiNo<T>is_ref() -> bool - Returns true if this is a referenceis_link() -> bool - Returns true if this is a linkparse_lino(document: &str) -> Result<LiNo<String>, String>Parses a Links Notation document string and returns the parsed structure or an error.
The Display trait is implemented for LiNo<T> where T: ToString:
format!("{}", lino) - Parenthesized outputformat!("{:#}", lino) - Line-based outputCheck code formatting:
cargo fmt --all -- --check
Auto-fix formatting:
cargo fmt --all
Run Clippy linter:
cargo clippy --all-targets --all-features -- -D warnings
This project uses pre-commit hooks that automatically run cargo fmt and
cargo check before commits. To set up pre-commit hooks locally:
# From repository root
pip install pre-commit
pre-commit install
The parser returns descriptive error messages for:
match parse_lino("(invalid") {
Ok(parsed) => println!("Parsed: {}", parsed),
Err(error) => eprintln!("Error: {}", error),
}
This project uses rustfmt for code formatting and clippy for linting.
cargo fmt
cargo fmt --check
cargo clippy
These checks are also enforced in CI. Pull requests with formatting issues will fail the format check.