drawbridge_server/store/
mod.rs

1// SPDX-FileCopyrightText: 2022 Profian Inc. <opensource@profian.com>
2// SPDX-License-Identifier: Apache-2.0
3mod 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    /// Initalizes a new [Store] at `root`
38    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}