cob: improve Comment generics
`Infallible` is a more appropriate type in comparsion to `()` for comments that do not require a `CodeLocation`. That is because if the type for `location` is `Option<()>`, this means that `Some(())` can be constructed, however, we never intend to construct that variant. On the other hand, `Infallible` can never be constructed, and so, only `None` can be used. This requires updates to some functions to use the generic `T` and also handle the different kinds of `Comment`s -- `Infallible` and `CodeLocation`. X-Co-Authored-By: Fintan Halpenny <fintan.halpenny@gmail.com>
This commit is contained in:
parent
48843434c7
commit
1f36879aa2
|
|
@ -5,9 +5,9 @@ use crate::terminal as term;
|
|||
use crate::terminal::format::Author;
|
||||
|
||||
/// Return a comment header as a [`term::Element`].
|
||||
pub fn header(
|
||||
pub fn header<T>(
|
||||
id: &CommentId,
|
||||
comment: &Comment,
|
||||
comment: &Comment<T>,
|
||||
profile: &Profile,
|
||||
) -> term::hstack::HStack<'static> {
|
||||
let author = comment.author();
|
||||
|
|
@ -27,7 +27,7 @@ pub fn header(
|
|||
}
|
||||
|
||||
/// Return a full comment widget as a [`term::Element`].
|
||||
pub fn widget<'a>(id: &CommentId, comment: &Comment, profile: &Profile) -> term::VStack<'a> {
|
||||
pub fn widget<'a, T>(id: &CommentId, comment: &Comment<T>, profile: &Profile) -> term::VStack<'a> {
|
||||
term::vstack::bordered(header(id, comment, profile))
|
||||
.child(term::textarea(comment.body()).wrap(60))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ pub(crate) fn issue(id: IssueId, issue: Issue, aliases: &impl AliasStore) -> Val
|
|||
"title": issue.title(),
|
||||
"state": issue.state(),
|
||||
"assignees": issue.assignees().collect::<Vec<_>>(),
|
||||
"discussion": issue.comments().map(|(id, c)| comment(id, c, aliases)).collect::<Vec<_>>(),
|
||||
"discussion": issue.comments().map(|(id, c)| issue_comment(id, c, aliases)).collect::<Vec<_>>(),
|
||||
"labels": issue.labels().collect::<Vec<_>>(),
|
||||
})
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ pub(crate) fn patch(
|
|||
"base": rev.base(),
|
||||
"oid": rev.head(),
|
||||
"refs": get_refs(repo, patch.author().id(), &rev.head()).unwrap_or_default(),
|
||||
"discussions": rev.discussion().comments().map(|(id, c)| comment(id, c, aliases)).collect::<Vec<_>>(),
|
||||
"discussions": rev.discussion().comments().map(|(id, c)| patch_comment(id, c, aliases)).collect::<Vec<_>>(),
|
||||
"timestamp": rev.timestamp().as_secs(),
|
||||
"reviews": rev.reviews().map(|(nid, r)| review(nid, r, aliases)).collect::<Vec<_>>(),
|
||||
})
|
||||
|
|
@ -172,8 +172,8 @@ fn review(nid: &NodeId, review: &Review, aliases: &impl AliasStore) -> Value {
|
|||
})
|
||||
}
|
||||
|
||||
/// Returns JSON for a `Comment`.
|
||||
fn comment(id: &CommentId, comment: &Comment, aliases: &impl AliasStore) -> Value {
|
||||
/// Returns JSON for a Issue `Comment`.
|
||||
fn issue_comment(id: &CommentId, comment: &Comment, aliases: &impl AliasStore) -> Value {
|
||||
json!({
|
||||
"id": *id,
|
||||
"author": author(&Author::from(comment.author()), aliases.alias(&comment.author())),
|
||||
|
|
@ -194,6 +194,33 @@ fn comment(id: &CommentId, comment: &Comment, aliases: &impl AliasStore) -> Valu
|
|||
})
|
||||
}
|
||||
|
||||
/// Returns JSON for a Patch `Comment`.
|
||||
fn patch_comment(
|
||||
id: &CommentId,
|
||||
comment: &Comment<CodeLocation>,
|
||||
aliases: &impl AliasStore,
|
||||
) -> Value {
|
||||
json!({
|
||||
"id": *id,
|
||||
"author": author(&Author::from(comment.author()), aliases.alias(&comment.author())),
|
||||
"body": comment.body(),
|
||||
"edits": comment.edits().map(|edit| {
|
||||
json!({
|
||||
"author": author(&Author::from(edit.author), aliases.alias(&edit.author)),
|
||||
"body": edit.body,
|
||||
"timestamp": edit.timestamp.as_secs(),
|
||||
"embeds": edit.embeds,
|
||||
})
|
||||
}).collect::<Vec<_>>(),
|
||||
"embeds": comment.embeds().to_vec(),
|
||||
"reactions": comment.reactions().collect::<Vec<_>>(),
|
||||
"timestamp": comment.timestamp().as_secs(),
|
||||
"replyTo": comment.reply_to(),
|
||||
"location": comment.location(),
|
||||
"resolved": comment.resolved(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns JSON for a `Review`.
|
||||
fn review_comment(
|
||||
id: &CommentId,
|
||||
|
|
|
|||
|
|
@ -3041,6 +3041,7 @@ mod routes {
|
|||
"reactions": [["z6Mkk7oqY4pPxhMmGEotDYsFo97vhCj85BLY1H256HrJmjN8","🚀"]],
|
||||
"timestamp": TIMESTAMP,
|
||||
"replyTo": null,
|
||||
"location": null,
|
||||
"resolved": false,
|
||||
},
|
||||
{
|
||||
|
|
@ -3063,6 +3064,7 @@ mod routes {
|
|||
"reactions": [],
|
||||
"timestamp": TIMESTAMP,
|
||||
"replyTo": comment_id,
|
||||
"location": null,
|
||||
"resolved": false,
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1012,7 +1012,7 @@ impl Patch {
|
|||
body,
|
||||
reply_to,
|
||||
embeds,
|
||||
..
|
||||
location,
|
||||
} => {
|
||||
if let Some(revision) = lookup::revision_mut(self, &revision)? {
|
||||
thread::comment(
|
||||
|
|
@ -1022,7 +1022,7 @@ impl Patch {
|
|||
timestamp,
|
||||
body,
|
||||
reply_to,
|
||||
None,
|
||||
location,
|
||||
embeds,
|
||||
)?;
|
||||
}
|
||||
|
|
@ -1255,7 +1255,7 @@ pub struct Revision {
|
|||
/// Reference to the Git object containing the code (revision head).
|
||||
pub(super) oid: git::Oid,
|
||||
/// Discussion around this revision.
|
||||
pub(super) discussion: Thread<Comment>,
|
||||
pub(super) discussion: Thread<Comment<CodeLocation>>,
|
||||
/// Reviews of this revision's changes (one per actor).
|
||||
pub(super) reviews: BTreeMap<ActorId, Option<Review>>,
|
||||
/// When this revision was created.
|
||||
|
|
@ -1313,7 +1313,7 @@ impl Revision {
|
|||
}
|
||||
|
||||
/// Discussion around this revision.
|
||||
pub fn discussion(&self) -> &Thread<Comment> {
|
||||
pub fn discussion(&self) -> &Thread<Comment<CodeLocation>> {
|
||||
&self.discussion
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::convert::Infallible;
|
||||
use std::str::FromStr;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
|
|
@ -67,7 +68,7 @@ pub struct Edit {
|
|||
|
||||
/// A comment on a discussion thread.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Comment<T = ()> {
|
||||
pub struct Comment<T = Infallible> {
|
||||
/// Comment author.
|
||||
author: ActorId,
|
||||
/// The comment body.
|
||||
|
|
@ -265,7 +266,7 @@ impl From<Action> for nonempty::NonEmpty<Action> {
|
|||
|
||||
/// A discussion thread.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Thread<T = Comment<()>> {
|
||||
pub struct Thread<T = Comment> {
|
||||
/// The comments under the thread.
|
||||
pub(crate) comments: BTreeMap<CommentId, Option<T>>,
|
||||
/// Comment timeline.
|
||||
|
|
|
|||
Loading…
Reference in New Issue