nix-nar-cli 0.2.1

Binary to manipulate Nix Archive (nar) files
use anyhow::bail;
use clap::Parser;
use nix_nar::{self, Content, Decoder};
use std::{
    fs::File,
    io::{self, BufReader, Write},
    path::PathBuf,
};

#[derive(Parser)]
pub struct Opts {
    /// NAR file to inspect.
    pub nar: PathBuf,

    /// Path inside the NAR file to print.
    pub path: PathBuf,
}

pub fn run<W: Write>(
    mut w: W,
    Opts {
        nar,
        path: path_to_print,
    }: Opts,
) -> Result<(), anyhow::Error> {
    let file = BufReader::new(File::open(nar)?);
    let dec = Decoder::new(file)?;
    let mut something_printed = false;
    for entry in dec.entries()? {
        let entry = entry?;
        if entry.abs_path() == path_to_print {
            match entry.content {
                Content::Directory | Content::Symlink { .. } => {
                    bail!("path '{}' is not a regular file", path_to_print.display())
                }
                Content::File { mut data, .. } => {
                    io::copy(&mut data, &mut w)?;
                    something_printed = true;
                    break;
                }
            }
        }
    }
    if !something_printed {
        bail!("path '{}' does not exist", path_to_print.display());
    }
    Ok(())
}