fhir-diff 0.1.2

Semantic diff of FHIR packages and profiles with a breaking-change gate
Documentation
//! Print one profile's effective tree at some paths: `cargo run --example dump -- <pkg> <url> <path>...`
use fhir_diff::{Node, Pool, load};

fn find<'a>(node: &'a Node, path: &[&str]) -> Option<&'a Node> {
    match path.split_first() {
        None => Some(node),
        Some((head, rest)) => {
            let (name, slice) = head
                .split_once(':')
                .map_or((*head, None), |(n, s)| (n, Some(s)));
            let child = node.children.get(name)?;
            let child = match slice {
                Some(s) => child.slices.get(s)?,
                None => child,
            };
            find(child, rest)
        }
    }
}

fn main() {
    let args: Vec<String> = std::env::args().skip(1).collect();
    let loaded = load(&args[0]).expect("load");
    let pool = Pool::new(&loaded);
    let profile = pool
        .profiles()
        .into_iter()
        .find(|p| p.url == args[1] || p.name == args[1])
        .expect("profile");
    for path in &args[2..] {
        let parts: Vec<&str> = path.split('.').collect();
        match find(&profile.tree, &parts) {
            Some(n) => println!(
                "{path}: min={} max={:?} types={:?} ms={} slices={:?} children={:?}",
                n.min,
                n.max,
                n.types,
                n.must_support,
                n.slices.keys().collect::<Vec<_>>(),
                n.children.keys().collect::<Vec<_>>()
            ),
            None => println!("{path}: (absent)"),
        }
    }
}