Skip to main content

snix_store/nar/narcalculationservice/
mod.rs

1use auto_impl::auto_impl;
2use nix_compat::nixhash::Sha256Digester;
3use snix_castore::{Node, blobservice::BlobService, directoryservice::DirectoryService};
4use tokio_util::io::InspectWriter;
5use tonic::async_trait;
6
7use crate::{nar::write_nar, pathinfoservice};
8
9#[cfg_attr(any(test, feature = "mocks"), mockall::automock)]
10#[async_trait]
11#[auto_impl(&, &mut, Arc, Box)]
12pub trait NarCalculationService: Send + Sync {
13    /// Return the nar size and nar sha256 digest for a given root node.
14    /// This can be used to calculate NAR-based output paths.
15    async fn calculate_nar(
16        &self,
17        root_node: &Node,
18    ) -> Result<(u64, [u8; 32]), pathinfoservice::Error>;
19}
20
21/// [NarCalculationService] traversing the node and rendering the NAR
22/// to calculate NAR hash and size.
23pub struct Renderer<BS, DS> {
24    blob_service: BS,
25    directory_service: DS,
26}
27
28impl<BS, DS> Renderer<BS, DS> {
29    pub fn new(blob_service: BS, directory_service: DS) -> Self {
30        Self {
31            blob_service,
32            directory_service,
33        }
34    }
35}
36
37#[async_trait]
38impl<BS, DS> NarCalculationService for Renderer<BS, DS>
39where
40    BS: BlobService,
41    DS: DirectoryService,
42{
43    async fn calculate_nar(
44        &self,
45        root_node: &Node,
46    ) -> Result<(u64, [u8; 32]), pathinfoservice::Error> {
47        // Invoke [write_nar], and return the size and sha256 digest of the produced NAR output.
48        let mut digester = Sha256Digester::new();
49
50        let mut nar_size = 0;
51        let writer = InspectWriter::new(tokio::io::sink(), |data| {
52            nar_size += data.len() as u64;
53            digester.update(data);
54        });
55
56        write_nar(
57            writer,
58            root_node,
59            &self.blob_service,
60            &self.directory_service,
61        )
62        .await?;
63
64        Ok((nar_size, digester.finalize().into()))
65    }
66}