nix-nar-cli 0.4.0

Binary to manipulate Nix Archive (nar) files
use std::{
    fs::File,
    io::{self, BufReader, Write},
};

use anyhow::bail;
use camino::Utf8PathBuf;
use clap::Parser;
use nix_nar::{self, Content, Decoder};

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

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

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 '{path_to_print}' is not a regular file")
                }
                Content::File { mut data, .. } => {
                    io::copy(&mut data, &mut w)?;
                    something_printed = true;
                    break;
                }
            }
        }
    }
    if !something_printed {
        bail!("path '{path_to_print}' does not exist");
    }
    Ok(())
}