libyang 2.0.1

YANG parser in Rust
docs.rs failed to build libyang-2.0.1
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

libyang

A YANG parser and data-modeling library written in Rust.

YANG (RFC 7950) is the data modeling language used to describe configuration and state data for network management protocols such as NETCONF and RESTCONF. libyang parses YANG modules, resolves their dependencies, and turns them into a tree you can walk to drive configuration and validation.

Features

  • RFC 7950 grammar, parsed with a parol-generated parser.
  • Module loading with automatic import / include (submodule) resolution.
  • typedef, grouping, identity, and union resolution.
  • An Entry tree suitable for building config schemas and validators.
  • Deterministic output: the tree has the same shape on every run, so it can be diffed or used to generate golden files.
  • Errors and schema problems are returned, never printed.

Installation

Add it to your Cargo.toml:

[dependencies]
libyang = "2"

Usage

Load a module by name from a search path, resolve its dependencies, and build the Entry tree:

use libyang::{to_entry, YangStore};

let mut store = YangStore::new();
store.add_path("yang"); // directory containing your .yang files

// Parse the module and everything it imports/includes.
store.read_with_resolve("ietf-bgp").expect("parse and resolve");
store.identity_resolve();

let module = store.find_module("ietf-bgp").expect("module found");
let entry = to_entry(&store, module);

println!("loaded module: {}", entry.name);

For low-level access, you can parse a single file into the grammar AST directly:

use libyang::yang;
use libyang::yang_grammar::YangGrammar;
use libyang::yang_parser::parse;

let input = std::fs::read_to_string("yang/ietf-bgp@2023-07-05.yang").unwrap();
let mut grammar = YangGrammar::new();
parse(&input, "ietf-bgp", &mut grammar).expect("parse");

let node = yang(grammar).expect("build node tree");

Diagnostics

A malformed augment — a target that does not resolve, one that lands on a leaf, or one that introduces a name the target already has — does not stop the build: the tree is still produced with that augment skipped. Those findings are collected on the store rather than written to stderr, so the caller decides whether to log them, fail, or ignore them:

use libyang::{to_entry, YangStore};

let mut store = YangStore::new();
store.add_path("yang");
store.read_with_resolve("ietf-bgp").expect("parse and resolve");
store.identity_resolve();

let module = store.find_module("ietf-bgp").expect("module found");
let entry = to_entry(&store, module);

for diagnostic in store.take_diagnostics() {
    eprintln!("warning: {diagnostic}");
}

Each Diagnostic names the module at fault along with the target and the offending node, and can be matched on rather than parsed.

Migrating from 1.x

2.0 is a breaking release:

  • YangStore::read is gone. Use read_with_resolve, which loads each module once (so mutually importing modules terminate) and keeps submodules.
  • YangStore::modules and submodules are private. Use find_module / find_submodule.
  • YangError's variants carry the file, module and underlying parse diagnostic, and the enum is #[non_exhaustive]. Parse failures are returned instead of being printed to stdout.
  • Augment problems are collected as Diagnostics (see above) instead of being written to stderr.
  • RangeNode implements Display instead of having an inherent to_string; .to_string() still works.

How it works

The pipeline runs in four stages:

  1. Parse — YANG text is parsed by the parol-generated grammar into a YangGrammar AST.
  2. ASTyang() converts the grammar tree into structured Node values.
  3. ResolveYangStore loads imports and includes, keeping submodules addressable through find_submodule, and resolves typedefs, groupings, and identities. Modules that import each other are loaded once, so cycles terminate.
  4. Entryto_entry() produces an Entry tree for data modeling and validation.

Testing

cargo test

Integration tests live in tests/ and run against fixture modules in tests/yang/ and the standard modules in yang/.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.