snix_castore/fs/
root_nodes.rs

1use std::collections::BTreeMap;
2
3use crate::nodes::Directory;
4use crate::{Error, Node, path::PathComponent};
5use futures::StreamExt;
6use futures::stream::BoxStream;
7use tonic::async_trait;
8
9/// Provides an interface for looking up root nodes  in snix-castore by given
10/// a lookup key (usually the basename), and optionally allow a listing.
11#[async_trait]
12pub trait RootNodes {
13    /// Looks up a root CA node based on the basename of the node in the root
14    /// directory of the filesystem.
15    async fn get_by_basename(&self, name: &PathComponent) -> Result<Option<Node>, Error>;
16
17    /// Lists all root CA nodes in the filesystem, as a tuple of (base)name
18    /// and Node.
19    /// An error can be returned in case listing is not allowed.
20    fn list(&self) -> BoxStream<'static, Result<(PathComponent, Node), Error>>;
21}
22
23#[async_trait]
24/// Implements RootNodes for something deref'ing to a BTreeMap of Nodes, where
25/// the key is the node name.
26impl<T> RootNodes for T
27where
28    T: AsRef<BTreeMap<PathComponent, Node>> + Send + Sync,
29{
30    async fn get_by_basename(&self, name: &PathComponent) -> Result<Option<Node>, Error> {
31        Ok(self.as_ref().get(name).cloned())
32    }
33
34    fn list(&self) -> BoxStream<'static, Result<(PathComponent, Node), Error>> {
35        let data = self.as_ref().to_owned();
36        futures::stream::iter(data.into_iter().map(Ok)).boxed()
37    }
38}
39
40#[async_trait]
41impl RootNodes for Directory {
42    async fn get_by_basename(&self, name: &PathComponent) -> Result<Option<Node>, Error> {
43        Ok(self
44            .nodes()
45            .find(|(key, _)| *key == name)
46            .map(|(_, node)| node.clone()))
47    }
48
49    fn list(&self) -> BoxStream<'static, Result<(PathComponent, Node), Error>> {
50        let data = self.to_owned();
51        futures::stream::iter(data.into_nodes().map(Ok)).boxed()
52    }
53}