snix_store/pathinfoservice/fs/
mod.rs

1use futures::stream::BoxStream;
2use futures::{StreamExt, TryStreamExt};
3use nix_compat::store_path::StorePathRef;
4use snix_castore::fs::RootNodes;
5use snix_castore::{Node, PathComponent};
6use tonic::async_trait;
7
8use super::PathInfoService;
9
10/// Wrapper to satisfy Rust's orphan rules for trait implementations, as
11/// RootNodes is coming from the [snix-castore] crate.
12#[doc(hidden)]
13#[derive(Clone, Debug)]
14pub struct RootNodesWrapper<T>(T);
15
16impl<T> From<T> for RootNodesWrapper<T>
17where
18    T: PathInfoService,
19{
20    fn from(value: T) -> Self {
21        Self(value)
22    }
23}
24
25#[derive(thiserror::Error, Debug)]
26#[error(transparent)]
27pub struct Error(#[from] super::Error);
28
29/// Implements root node lookup for any [PathInfoService]. This represents a flat
30/// directory structure like /nix/store where each entry in the root filesystem
31/// directory corresponds to a CA node.
32#[cfg(any(feature = "fuse", feature = "virtiofs"))]
33#[async_trait]
34impl<T> RootNodes for RootNodesWrapper<T>
35where
36    T: PathInfoService,
37{
38    type Error = Error;
39
40    async fn get_by_basename(&self, name: &PathComponent) -> Result<Option<Node>, Self::Error> {
41        let Ok(store_path) = StorePathRef::from_bytes(name.as_ref()) else {
42            return Ok(None);
43        };
44
45        Ok(self
46            .0
47            .get(*store_path.digest())
48            .await?
49            .map(|path_info| path_info.node))
50    }
51
52    fn list(&self) -> BoxStream<'static, Result<(PathComponent, Node), Self::Error>> {
53        self.0
54            .list()
55            .map_ok(|path_info| {
56                let name = path_info
57                    .store_path
58                    .to_string()
59                    .as_str()
60                    .try_into()
61                    .expect("Snix bug: StorePath must be PathComponent");
62                (name, path_info.node)
63            })
64            .err_into()
65            .boxed()
66    }
67}