tiedcrossing_client/
tag.rs1use super::{Entity, Node, Result};
5
6use std::collections::BTreeMap;
7use std::ops::Deref;
8use std::path::Path;
9
10use drawbridge_jose::jws::Jws;
11use drawbridge_jose::MediaTyped;
12use drawbridge_type::TreeContent::{Directory, File};
13use drawbridge_type::{TagEntry, TagName, Tree, TreeEntry, TreePath};
14
15use ureq::serde::Serialize;
16
17pub struct Tag<'a>(Entity<'a>);
18
19impl<'a> Deref for Tag<'a> {
20 type Target = Entity<'a>;
21
22 fn deref(&self) -> &Self::Target {
23 &self.0
24 }
25}
26
27impl<'a> Tag<'a> {
28 pub fn new(entity: Entity<'a>, name: &TagName) -> Self {
29 Tag(entity.child(&name.to_string()))
30 }
31
32 pub fn create(&self, entry: &TagEntry<impl Serialize>) -> Result<bool> {
33 let mime = match entry {
34 TagEntry::Unsigned(..) => TreeEntry::<()>::TYPE,
35 TagEntry::Signed(..) => Jws::TYPE,
36 }
37 .parse()
38 .expect("failed to parse tag entry media type");
39 self.0.create_json(&mime, entry)
40 }
41
42 pub fn create_from_path_unsigned(
44 &self,
45 path: impl AsRef<Path>,
46 ) -> Result<(bool, BTreeMap<TreePath, bool>)> {
47 let tree = Tree::from_path_sync(path)?;
48 let tag_created = self.create(&TagEntry::Unsigned(tree.root()))?;
49 let tree_created = tree
50 .into_iter()
51 .map(
52 |(
53 path,
54 TreeEntry {
55 ref meta,
56 ref content,
57 ..
58 },
59 )| {
60 let node = Node::new(self.child("tree"), &path);
61 let created = match content {
62 File(file) => node.create_from(meta, file)?,
63 Directory(buf) => node.create_from(meta, buf.as_slice())?,
64 };
65 Ok((path, created))
66 },
67 )
68 .collect::<Result<_>>()?;
69 Ok((tag_created, tree_created))
70 }
71
72 pub fn get(&self) -> Result<TagEntry> {
73 self.0.get_json()
74 }
75
76 pub fn path(&self, path: &TreePath) -> Node<'a> {
77 Node::new(self.child("tree"), path)
78 }
79}