drawbridge_server/store/
tag.rs1use super::{CreateError, Entity, Node};
5
6use std::ops::Deref;
7
8use drawbridge_type::{Meta, TreeDirectory, TreeEntry, TreePath};
9
10use camino::{Utf8Path, Utf8PathBuf};
11use futures::{try_join, AsyncRead};
12use tracing::debug;
13
14#[repr(transparent)]
15#[derive(Copy, Clone, Debug)]
16pub struct Tag<'a, P = Utf8PathBuf>(Entity<'a, P>);
17
18impl<'a, P> Deref for Tag<'a, P> {
19 type Target = Entity<'a, P>;
20
21 fn deref(&self) -> &Self::Target {
22 &self.0
23 }
24}
25
26impl<'a, P> From<Entity<'a, P>> for Tag<'a, P> {
27 fn from(entity: Entity<'a, P>) -> Self {
28 Self(entity)
29 }
30}
31
32impl<'a, P: AsRef<Utf8Path>> Tag<'a, P> {
33 pub fn node(&self, path: &TreePath) -> Node<'a, Utf8PathBuf> {
34 if path.is_empty() {
35 self.0.child("tree").into()
36 } else {
37 self.0
38 .child(format!("tree/entries/{}", path.intersperse("/entries/")))
39 .into()
40 }
41 }
42
43 pub async fn create_file_node(
44 &self,
45 path: &TreePath,
46 meta: Meta,
47 rdr: impl Unpin + AsyncRead,
48 ) -> Result<Node<'a, Utf8PathBuf>, CreateError<anyhow::Error>> {
49 let node = self.node(path);
52 node.create_dir("").await.map_err(|e| {
53 debug!(target: "app::store::Tag::create_file_node", "failed to create content directory: {:?}", e);
54 e
55 })?;
56 node.create_from_reader(meta, rdr).await?;
57 Ok(node)
58 }
59
60 pub async fn create_directory_node(
61 &self,
62 path: &TreePath,
63 meta: Meta,
64 dir: &TreeDirectory<TreeEntry>,
65 ) -> Result<Node<'a, Utf8PathBuf>, CreateError<anyhow::Error>> {
66 let node = self.node(path);
69 node.create_dir("").await.map_err(|e| {
70 debug!(target: "app::store::Tag::create_directory_node", "failed to create content directory: {:?}", e);
71 e
72 })?;
73 try_join!(node.create_json(meta, dir), node.create_dir("entries"))?;
74 Ok(node)
75 }
76}