drawbridge_server/store/
mod.rs1mod entity;
4mod repo;
5mod tag;
6mod tree;
7mod user;
8
9pub use entity::*;
10pub use repo::*;
11pub use tag::*;
12pub use tree::*;
13pub use user::*;
14
15use drawbridge_type::{Meta, RepositoryContext, TagContext, TreeContext, UserContext, UserRecord};
16
17use async_std::io;
18use camino::{Utf8Path, Utf8PathBuf};
19use cap_async_std::fs_utf8::Dir;
20use futures::try_join;
21
22#[derive(Debug)]
23pub struct Store {
24 root: Dir,
25}
26
27async fn upsert_dir(root: &Dir, path: impl AsRef<Utf8Path>) -> io::Result<()> {
28 let path = path.as_ref();
29 if !root.is_dir(path).await {
30 root.create_dir(path)
31 } else {
32 Ok(())
33 }
34}
35
36impl Store {
37 pub async fn new(root: Dir) -> io::Result<Self> {
39 upsert_dir(&root, "users").await?;
40 Ok(Self { root })
41 }
42
43 pub fn user(&self, UserContext { name }: &UserContext) -> User<'_, Utf8PathBuf> {
44 Entity::new(&self.root)
45 .child(format!("users/{name}"))
46 .into()
47 }
48
49 pub async fn create_user(
50 &self,
51 cx: &UserContext,
52 meta: Meta,
53 rec: &UserRecord,
54 ) -> Result<User<'_>, CreateError<anyhow::Error>> {
55 let user = self.user(cx);
56 user.create_dir("").await?;
57 try_join!(user.create_json(meta, rec), user.create_dir("repos"),)?;
58 Ok(user)
59 }
60
61 pub fn repository<'a>(
62 &'a self,
63 RepositoryContext { owner, name }: &'a RepositoryContext,
64 ) -> Repository<'_> {
65 self.user(owner).repository(name)
66 }
67
68 pub fn tag<'a>(&'a self, TagContext { repository, name }: &'a TagContext) -> Tag<'_> {
69 self.repository(repository).tag(name)
70 }
71
72 pub fn tree<'a>(&'a self, TreeContext { tag, path }: &'a TreeContext) -> Node<'_> {
73 self.tag(tag).node(path)
74 }
75}