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
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    type Error: std::error::Error + Send + Sync + 'static;
14    /// Looks up a root CA node based on the basename of the node in the root
15    /// directory of the filesystem.
16    async fn get_by_basename(&self, name: &PathComponent) -> Result<Option<Node>, Self::Error>;
17
18    /// Lists all root CA nodes in the filesystem, as a tuple of (base)name
19    /// and Node.
20    /// An error can be returned in case listing is not allowed.
21    fn list(&self) -> BoxStream<'static, Result<(PathComponent, Node), Self::Error>>;
22}
23
24#[async_trait]
25/// Implements RootNodes for something deref'ing to a BTreeMap of Nodes, where
26/// the key is the node name.
27impl<T> RootNodes for T
28where
29    T: AsRef<BTreeMap<PathComponent, Node>> + Send + Sync,
30{
31    type Error = std::io::Error; // infallible, really.
32
33    async fn get_by_basename(&self, name: &PathComponent) -> Result<Option<Node>, Self::Error> {
34        Ok(self.as_ref().get(name).cloned())
35    }
36
37    fn list(&self) -> BoxStream<'static, Result<(PathComponent, Node), Self::Error>> {
38        let data = self.as_ref().to_owned();
39        futures::stream::iter(data.into_iter().map(Ok)).boxed()
40    }
41}
42
43#[async_trait]
44impl RootNodes for Directory {
45    type Error = std::io::Error; // infallible, really.
46
47    async fn get_by_basename(&self, name: &PathComponent) -> Result<Option<Node>, Self::Error> {
48        Ok(self
49            .nodes()
50            .find(|(key, _)| *key == name)
51            .map(|(_, node)| node.clone()))
52    }
53
54    fn list(&self) -> BoxStream<'static, Result<(PathComponent, Node), Self::Error>> {
55        let data = self.to_owned();
56        futures::stream::iter(data.into_nodes().map(Ok)).boxed()
57    }
58}