Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
httpd: Add issue and patch counts
Sebastian Martinez committed 3 years ago
commit 97a2f8c1df19d816ee904895f0aba24870c1d9ff
parent 5ea8505000dea690699258e78ad16e2009af3fa6
5 files changed +86 -14
modified radicle-httpd/src/api.rs
@@ -51,8 +51,8 @@ impl Context {
        let doc = repo.identity_of(self.profile.id())?;
        let payload = doc.project()?;
        let delegates = doc.delegates;
-
        let issues = (Issues::open(self.profile.public_key, &repo)?).count()?;
-
        let patches = (Patches::open(self.profile.public_key, &repo)?).count()?;
+
        let issues = Issues::open(self.profile.public_key, &repo)?.counts()?;
+
        let patches = Patches::open(self.profile.public_key, &repo)?.counts()?;

        Ok(project::Info {
            payload,
@@ -143,6 +143,7 @@ mod project {
    use nonempty::NonEmpty;
    use serde::Serialize;

+
    use radicle::cob;
    use radicle::git::Oid;
    use radicle::identity::project::Project;
    use radicle::identity::Id;
@@ -157,8 +158,8 @@ mod project {
        pub payload: Project,
        pub delegates: NonEmpty<Did>,
        pub head: Oid,
-
        pub patches: usize,
-
        pub issues: usize,
+
        pub patches: cob::patch::PatchCounts,
+
        pub issues: cob::issue::IssueCounts,
        pub id: Id,
    }
}
modified radicle-httpd/src/api/v1/delegates.rs
@@ -49,9 +49,9 @@ async fn delegates_projects_handler(
            }

            let Ok(issues) = Issues::open(ctx.profile.public_key, &repo) else { return None };
-
            let Ok(issues) = (*issues).count() else { return None };
+
            let Ok(issues) = issues.counts() else { return None };
            let Ok(patches) = Patches::open(ctx.profile.public_key, &repo) else { return None };
-
            let Ok(patches) = (*patches).count() else { return None };
+
            let Ok(patches) = patches.counts() else { return None };

            Some(Info {
                payload,
@@ -96,8 +96,15 @@ mod routes {
                "defaultBranch": "master",
                "delegates": ["did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"],
                "head": HEAD,
-
                "patches": 1,
-
                "issues": 1,
+
                "patches": {
+
                  "proposed": 1,
+
                  "draft": 0,
+
                  "archived": 0,
+
                },
+
                "issues": {
+
                  "open": 1,
+
                  "closed": 0,
+
                },
                "id": "rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp"
              }
            ])
modified radicle-httpd/src/api/v1/projects.rs
@@ -81,9 +81,9 @@ async fn project_root_handler(
            let Ok(payload) = repo.project_of(ctx.profile.id()) else { return None };
            let Ok(doc) = repo.identity_of(ctx.profile.id()) else { return None };
            let Ok(issues) = Issues::open(ctx.profile.public_key, &repo) else { return None };
-
            let Ok(issues) = (*issues).count() else { return None };
+
            let Ok(issues) = issues.counts() else { return None };
            let Ok(patches) = Patches::open(ctx.profile.public_key, &repo) else { return None };
-
            let Ok(patches) = (*patches).count() else { return None };
+
            let Ok(patches) = patches.counts() else { return None };
            let delegates = doc.delegates;

            Some(Info {
@@ -583,8 +583,15 @@ mod routes {
                "defaultBranch": "master",
                "delegates": ["did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"],
                "head": HEAD,
-
                "patches": 1,
-
                "issues": 1,
+
                "patches": {
+
                  "proposed": 1,
+
                  "draft": 0,
+
                  "archived": 0,
+
                },
+
                "issues": {
+
                  "open": 1,
+
                  "closed": 0,
+
                },
                "id": "rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp"
              }
            ])
@@ -606,8 +613,15 @@ mod routes {
               "defaultBranch": "master",
               "delegates": ["did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"],
               "head": HEAD,
-
               "patches": 1,
-
               "issues": 1,
+
               "patches": {
+
                 "proposed": 1,
+
                 "draft": 0,
+
                 "archived": 0,
+
               },
+
               "issues": {
+
                 "open": 1,
+
                 "closed": 0,
+
               },
               "id": "rad:z4FucBZHZMCsxTyQE1dfE2YR59Qbp"
            })
        );
modified radicle/src/cob/issue.rs
@@ -385,6 +385,14 @@ impl<'a> Deref for Issues<'a> {
    }
}

+
/// Detailed information on issue states
+
#[derive(Default, Serialize)]
+
#[serde(rename_all = "camelCase")]
+
pub struct IssueCounts {
+
    pub open: usize,
+
    pub closed: usize,
+
}
+

impl<'a> Issues<'a> {
    /// Open an issues store.
    pub fn open(
@@ -443,6 +451,22 @@ impl<'a> Issues<'a> {
        })
    }

+
    /// Issues count by state.
+
    pub fn counts(&self) -> Result<IssueCounts, Error> {
+
        let all = self.all()?;
+
        let state_groups =
+
            all.filter_map(|s| s.ok())
+
                .fold(IssueCounts::default(), |mut state, (_, p, _)| {
+
                    match p.state() {
+
                        State::Open => state.open += 1,
+
                        State::Closed { .. } => state.closed += 1,
+
                    }
+
                    state
+
                });
+

+
        Ok(state_groups)
+
    }
+

    /// Remove an issue.
    pub fn remove(&self, id: &ObjectId) -> Result<(), store::Error> {
        self.raw.remove(id)
modified radicle/src/cob/patch.rs
@@ -758,6 +758,15 @@ impl<'a, 'g> Deref for PatchMut<'a, 'g> {
    }
}

+
/// Detailed information on patch states
+
#[derive(Default, Serialize)]
+
#[serde(rename_all = "camelCase")]
+
pub struct PatchCounts {
+
    pub proposed: usize,
+
    pub draft: usize,
+
    pub archived: usize,
+
}
+

pub struct Patches<'a> {
    raw: store::Store<'a, Patch>,
}
@@ -804,6 +813,23 @@ impl<'a> Patches<'a> {
        Ok(PatchMut::new(id, patch, clock, self))
    }

+
    /// Patches count by state.
+
    pub fn counts(&self) -> Result<PatchCounts, store::Error> {
+
        let all = self.all()?;
+
        let state_groups =
+
            all.filter_map(|s| s.ok())
+
                .fold(PatchCounts::default(), |mut state, (_, p, _)| {
+
                    match p.state() {
+
                        State::Draft => state.draft += 1,
+
                        State::Proposed => state.proposed += 1,
+
                        State::Archived => state.archived += 1,
+
                    }
+
                    state
+
                });
+

+
        Ok(state_groups)
+
    }
+

    /// Get a patch.
    pub fn get(&self, id: &ObjectId) -> Result<Option<Patch>, store::Error> {
        self.raw.get(id).map(|r| r.map(|(p, _)| p))