snix_store/pathinfoservice/fs/
mod.rs1use 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#[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#[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}