ipfs_unixfs/dir/builder/
dir_builder.rs

1use super::{Entry, Leaf};
2use crate::Metadata;
3use alloc::collections::btree_map::Entry::*;
4use alloc::collections::BTreeMap;
5
6pub(super) struct DuplicateName;
7pub(super) struct FoundLeaf;
8
9/// Node in a directory tree.
10#[derive(Debug)]
11pub(super) struct DirBuilder {
12    /// Immediate files, symlinks or directories in this directory
13    pub nodes: BTreeMap<String, Entry>,
14    /// Metadata for this directory
15    metadata: Metadata,
16    /// Id of the parent; None for the root node
17    pub parent_id: Option<u64>,
18    /// Internal id, used for propagating Cids back from children during post order visit.
19    pub id: u64,
20}
21
22impl DirBuilder {
23    pub fn new(parent_id: u64, id: u64) -> Self {
24        assert_ne!(parent_id, id);
25        DirBuilder {
26            nodes: Default::default(),
27            metadata: Default::default(),
28            parent_id: Some(parent_id),
29            id,
30        }
31    }
32
33    pub fn root(id: u64) -> Self {
34        DirBuilder {
35            nodes: Default::default(),
36            metadata: Default::default(),
37            parent_id: None,
38            id,
39        }
40    }
41
42    pub fn put_leaf(&mut self, key: String, leaf: Leaf) -> Result<(), DuplicateName> {
43        match self.nodes.entry(key) {
44            Occupied(_) => Err(DuplicateName),
45            Vacant(ve) => {
46                ve.insert(Entry::Leaf(leaf));
47                Ok(())
48            }
49        }
50    }
51
52    pub fn add_or_get_node(
53        &mut self,
54        key: String,
55        id: &mut Option<u64>,
56    ) -> Result<&mut DirBuilder, FoundLeaf> {
57        match self.nodes.entry(key) {
58            Occupied(oe) => oe.into_mut().as_dir_builder().map_err(|_| FoundLeaf),
59            Vacant(ve) => {
60                let id = id.take().unwrap();
61                let entry = ve.insert(Entry::Directory(Self::new(self.id, id)));
62                Ok(entry.as_dir_builder().expect("just inserted"))
63            }
64        }
65    }
66
67    pub fn len(&self) -> usize {
68        self.nodes.len()
69    }
70
71    pub fn is_empty(&self) -> bool {
72        self.len() == 0
73    }
74
75    pub fn set_metadata(&mut self, metadata: Metadata) {
76        self.metadata = metadata;
77    }
78}