Open Pegasust opened 1 year ago
@Pegasust this crate merely provides high-level bindings for libyang2 using idiomatic Rust. What you're probably looking for is a tool that generates Rust code from YANG modules, along with the ability to transform auto-generated Rust structs to and from JSON/XML. In short, something similar to what ygot does in the Go ecosystem.
However, you can leverage yang2-rs to generate Rust code from the YANG modules yourself. This can be done in a build script so that the generated code is available for use in your main crate. I'm currently using this approach in the Holo project [1], but the code I generate is currently quite basic, consisting of a hierarchy of modules and their corresponding data paths.
libyang2-sys
won't help you at all since it only provides raw FFI bindings for libyang2.
[1] https://github.com/holo-routing/holo/blob/master/holo-northbound/build.rs
Hmm, I don't think I need to generate Rust code itself yet, merely walking through modules and schemas and getting an intermediate tree/DAG structure for the purpose of dumb config tree verification in-memory is what I'm seeking.
I'll checkout the linked projects later, thanks for the pointers!
I thought libyang2-sys would help because I remember looking through libyang and saw a module walker from a configured subdir/searchdir
On Thu, Nov 9, 2023, 6:09 PM Renato Westphal @.***> wrote:
@Pegasust https://github.com/Pegasust this crate merely provides high-level bindings for libyang2 using idiomatic Rust. What you're probably looking for is a tool that generates Rust code from YANG modules, along with the ability to transform auto-generated Rust structs to and from JSON/XML. In short, something similar to what ygot https://github.com/openconfig/ygot does in the Go ecosystem.
However, you can leverage yang2-rs to generate Rust code from the YANG modules yourself. This can be done in a build script so that the generated code is available for use in your main crate. I'm currently using this approach in the Holo project [1], but the code I generate is currently quite basic, consisting of a hierarchy of modules and their corresponding data paths.
libyang2-sys won't help you at all since it only provides raw FFI bindings for libyang2.
[1] https://github.com/holo-routing/holo/blob/master/holo-northbound/build.rs
— Reply to this email directly, view it on GitHub https://github.com/holo-routing/yang2-rs/issues/12#issuecomment-1804966813, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIP4Y72XZG6V3TR77QKZ2B3YDWEFHAVCNFSM6AAAAAA7FL5JCKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMBUHE3DMOBRGM . You are receiving this because you were mentioned.Message ID: @.***>
Thanks so much for pointing to holo-routing
's monorepo. It really helps me understanding YANG a lot more and potentially use codegen for development inside Rust!
That said, from more diligent research, it seems libyang
, goyang
, and yanglint
in the case where they load all modules and resolve them as needed, they just expect the module name to be the same as the file name (without .yang
). As far as I can see, none of said tool do the parsing like programming languages onto intermediate syntax tree structure and resolve semantically only after all modules are parsed.
So despite not enforced in RFCs, conventionally, all module names are just the same as file name, correct?
Hmm, I don't think I need to generate Rust code itself yet, merely walking through modules and schemas and getting an intermediate tree/DAG structure for the purpose of dumb config tree verification in-memory is what I'm seeking.
Ok. If I understood you correctly, you want to load YANG modules dynamically instead of hardcoding their names in the source file.
libyang2 supports loading YANG modules directly from the filesystem using the lys_parse_path()
API, but that functionality isn't exposed by yang2-rs
, which only supports loading modules by their names [1].
You can, however, add a parse_module
method to the Context
struct as a wrapper for lys_parse_path()
and submit a PR for that. Alternatively, you can use the libyang2-sys raw bindings directly in your crate, but since using raw bindings requires unsafe code, it's usually better to abstract their usage within this crate.
Once you have Context::parse_module
, you can manually iterate through a directory and load all modules using that function.
So despite not enforced in RFCs, conventionally, all module names are just the same as file name, correct?
Exactly, it's just a convention. Generally, the module's revision is appended after the module name as well (e.g., ietf-bgp@2023-07-05.yang).
[1] https://docs.rs/yang2/latest/yang2/context/struct.Context.html#method.load_module
I want to build some sort of YANG model intelligence on some networking vendor, something like ensuring type-safety for a pre-configured schema and devtool for migration across versions.
As such, it's probably safe to say that it's impossible to know the modules before-hand. Seeing that we need to load modules, this throws me off. https://github.com/holo-routing/yang2-rs/blob/f8c939471a9eeb207477e79cd0a5b813614585e8/examples/data_diff.rs#L60-L62
Could I resort to
libyang2-sys
? If so, how?