httpd: Extract `issue` json response
Signed-off-by: xphoniex <dj.2dixx@gmail.com>
This commit is contained in:
parent
4552c1f296
commit
c1ba45fcd8
|
|
@ -2,9 +2,14 @@
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
use serde::Serialize;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
|
use radicle::cob::issue::{Issue, IssueId};
|
||||||
use radicle::cob::patch::{Patch, PatchId};
|
use radicle::cob::patch::{Patch, PatchId};
|
||||||
|
use radicle::cob::thread::{self, CommentId};
|
||||||
|
use radicle::cob::Timestamp;
|
||||||
|
use radicle::identity::PublicKey;
|
||||||
use radicle_surf::blob::Blob;
|
use radicle_surf::blob::Blob;
|
||||||
use radicle_surf::tree::Tree;
|
use radicle_surf::tree::Tree;
|
||||||
use radicle_surf::{Commit, Stats};
|
use radicle_surf::{Commit, Stats};
|
||||||
|
|
@ -62,6 +67,18 @@ pub(crate) fn tree(tree: &Tree, path: &str, stats: &Stats) -> Value {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns JSON for an `issue`.
|
||||||
|
pub(crate) fn issue(id: IssueId, issue: Issue) -> Value {
|
||||||
|
json!({
|
||||||
|
"id": id.to_string(),
|
||||||
|
"author": issue.author(),
|
||||||
|
"title": issue.title(),
|
||||||
|
"state": issue.state(),
|
||||||
|
"discussion": issue.comments().collect::<Comments>(),
|
||||||
|
"tags": issue.tags().collect::<Vec<_>>(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns JSON for a `patch`.
|
/// Returns JSON for a `patch`.
|
||||||
pub(crate) fn patch(id: PatchId, patch: Patch) -> Value {
|
pub(crate) fn patch(id: PatchId, patch: Patch) -> Value {
|
||||||
json!({
|
json!({
|
||||||
|
|
@ -89,3 +106,41 @@ fn name_in_path(path: &str) -> &str {
|
||||||
None => path,
|
None => path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Author {
|
||||||
|
id: PublicKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
struct Comment {
|
||||||
|
author: Author,
|
||||||
|
body: String,
|
||||||
|
reactions: [String; 0],
|
||||||
|
timestamp: Timestamp,
|
||||||
|
reply_to: Option<CommentId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct Comments(Vec<Comment>);
|
||||||
|
|
||||||
|
impl<'a> FromIterator<(&'a CommentId, &'a thread::Comment)> for Comments {
|
||||||
|
fn from_iter<I: IntoIterator<Item = (&'a CommentId, &'a thread::Comment)>>(iter: I) -> Self {
|
||||||
|
let mut comments = Vec::new();
|
||||||
|
|
||||||
|
for (_, comment) in iter {
|
||||||
|
comments.push(Comment {
|
||||||
|
author: Author {
|
||||||
|
id: comment.author(),
|
||||||
|
},
|
||||||
|
body: comment.body().to_owned(),
|
||||||
|
reactions: [],
|
||||||
|
timestamp: comment.timestamp(),
|
||||||
|
reply_to: comment.reply_to(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Comments(comments)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,7 @@ use tower_http::set_header::SetResponseHeaderLayer;
|
||||||
|
|
||||||
use radicle::cob::issue::Issues;
|
use radicle::cob::issue::Issues;
|
||||||
use radicle::cob::patch::Patches;
|
use radicle::cob::patch::Patches;
|
||||||
use radicle::cob::thread::{self, CommentId};
|
use radicle::identity::Id;
|
||||||
use radicle::cob::Timestamp;
|
|
||||||
use radicle::identity::{Id, PublicKey};
|
|
||||||
use radicle::node::NodeId;
|
use radicle::node::NodeId;
|
||||||
use radicle::storage::{git::paths, ReadRepository, WriteStorage};
|
use radicle::storage::{git::paths, ReadRepository, WriteStorage};
|
||||||
use radicle_surf::{Glob, Oid, Repository};
|
use radicle_surf::{Glob, Oid, Repository};
|
||||||
|
|
@ -385,16 +383,7 @@ async fn issues_handler(
|
||||||
.all()?
|
.all()?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|r| r.ok())
|
.filter_map(|r| r.ok())
|
||||||
.map(|(id, issue, _)| {
|
.map(|(id, issue, _)| api::json::issue(id, issue))
|
||||||
json!({
|
|
||||||
"id": id.to_string(),
|
|
||||||
"author": issue.author(),
|
|
||||||
"title": issue.title(),
|
|
||||||
"state": issue.state(),
|
|
||||||
"discussion": issue.comments().collect::<Comments>(),
|
|
||||||
"tags": issue.tags().collect::<Vec<_>>(),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.skip(page * per_page)
|
.skip(page * per_page)
|
||||||
.take(per_page)
|
.take(per_page)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
@ -413,16 +402,8 @@ async fn issue_handler(
|
||||||
let issue = Issues::open(ctx.profile.public_key, &repo)?
|
let issue = Issues::open(ctx.profile.public_key, &repo)?
|
||||||
.get(&issue_id.into())?
|
.get(&issue_id.into())?
|
||||||
.ok_or(Error::NotFound)?;
|
.ok_or(Error::NotFound)?;
|
||||||
let issue = json!({
|
|
||||||
"id": issue_id,
|
|
||||||
"author": issue.author(),
|
|
||||||
"title": issue.title(),
|
|
||||||
"state": issue.state(),
|
|
||||||
"discussion": issue.comments().collect::<Comments>(),
|
|
||||||
"tags": issue.tags().collect::<Vec<_>>(),
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok::<_, Error>(Json(issue))
|
Ok::<_, Error>(Json(api::json::issue(issue_id.into(), issue)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get project patches list.
|
/// Get project patches list.
|
||||||
|
|
@ -465,44 +446,6 @@ async fn patch_handler(
|
||||||
Ok::<_, Error>(Json(api::json::patch(patch_id.into(), patch)))
|
Ok::<_, Error>(Json(api::json::patch(patch_id.into(), patch)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
struct Author {
|
|
||||||
id: PublicKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
struct Comment {
|
|
||||||
author: Author,
|
|
||||||
body: String,
|
|
||||||
reactions: [String; 0],
|
|
||||||
timestamp: Timestamp,
|
|
||||||
reply_to: Option<CommentId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
struct Comments(Vec<Comment>);
|
|
||||||
|
|
||||||
impl<'a> FromIterator<(&'a CommentId, &'a thread::Comment)> for Comments {
|
|
||||||
fn from_iter<I: IntoIterator<Item = (&'a CommentId, &'a thread::Comment)>>(iter: I) -> Self {
|
|
||||||
let mut comments = Vec::new();
|
|
||||||
|
|
||||||
for (_, comment) in iter {
|
|
||||||
comments.push(Comment {
|
|
||||||
author: Author {
|
|
||||||
id: comment.author(),
|
|
||||||
},
|
|
||||||
body: comment.body().to_owned(),
|
|
||||||
reactions: [],
|
|
||||||
timestamp: comment.timestamp(),
|
|
||||||
reply_to: comment.reply_to(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Comments(comments)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod routes {
|
mod routes {
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue