snix_castore/fs/
root_nodes.rs

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