Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle: Add `schemars` to cob actions
Sebastian Martinez committed 9 months ago
commit 2a981d05e6a677df033162f86e6774703ecee4e0
parent 4934473b86b3a014afca8e5317b85c0c78cc58d3
7 files changed +160 -6
modified crates/radicle/src/cob/common.rs
@@ -81,6 +81,7 @@ pub enum ReactionError {
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Serialize)]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[serde(transparent)]
pub struct Reaction {
    emoji: char,
@@ -183,6 +184,7 @@ pub enum LabelError {

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Serialize, Deserialize)]
#[serde(transparent)]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Label(String);

impl Label {
@@ -278,6 +280,7 @@ impl<'a> Deserialize<'a> for Color {
/// A URI.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Serialize, Deserialize)]
#[serde(transparent)]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Uri(String);

impl Uri {
@@ -377,8 +380,10 @@ impl From<bool> for Authorization {
/// patches, issues, and diffs.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct CodeLocation {
    /// [`Oid`] of the Git commit.
+
    #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
    pub commit: Oid,
    /// Path of file.
    pub path: PathBuf,
@@ -391,6 +396,7 @@ pub struct CodeLocation {
/// Code range.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "type")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum CodeRange {
    /// One or more lines.
    Lines { range: Range<usize> },
modified crates/radicle/src/cob/identity.rs
@@ -41,6 +41,7 @@ pub type RevisionId = EntryId;
/// Proposal operation.
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum Action {
    #[serde(rename = "revision")]
    Revision {
@@ -51,14 +52,25 @@ pub enum Action {
        description: String,
        /// Blob identifier of the document included in this action as an embed.
        /// Hence, we do not include it as a parent of this action in [`CobAction`].
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        blob: Oid,
        /// Parent revision that this revision replaces.
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "Option<crate::schemars_ext::git::Oid>")
+
        )]
        parent: Option<RevisionId>,
        /// Signature over the revision blob.
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "crate::schemars_ext::crypto::Signature")
+
        )]
        signature: Signature,
    },
+
    #[serde(rename = "revision.edit")]
    RevisionEdit {
        /// The revision to edit.
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        revision: RevisionId,
        /// Short summary of changes.
        title: String,
@@ -68,14 +80,25 @@ pub enum Action {
    },
    #[serde(rename = "revision.accept")]
    RevisionAccept {
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        revision: RevisionId,
        /// Signature over the blob.
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "crate::schemars_ext::crypto::Signature")
+
        )]
        signature: Signature,
    },
    #[serde(rename = "revision.reject")]
-
    RevisionReject { revision: RevisionId },
+
    RevisionReject {
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
+
        revision: RevisionId,
+
    },
    #[serde(rename = "revision.redact")]
-
    RevisionRedact { revision: RevisionId },
+
    RevisionRedact {
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
+
        revision: RevisionId,
+
    },
}

impl CobAction for Action {
modified crates/radicle/src/cob/issue.rs
@@ -83,6 +83,7 @@ pub enum Error {
/// Reason why an issue was closed.
#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum CloseReason {
    Other,
    Solved,
@@ -101,6 +102,7 @@ impl std::fmt::Display for CloseReason {
/// Issue state.
#[derive(Debug, Default, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "status")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum State {
    /// The issue is closed.
    Closed { reason: CloseReason },
@@ -905,6 +907,7 @@ where
/// Issue action.
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum Action {
    /// Assign issue to an actor.
    #[serde(rename = "assign")]
@@ -932,9 +935,20 @@ pub enum Action {
        /// Should be [`None`] if it's the top-level comment.
        /// Should be the root [`CommentId`] if it's a top-level comment.
        #[serde(default, skip_serializing_if = "Option::is_none")]
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "Option<crate::schemars_ext::git::Oid>"),
+
            schemars(
+
                description = "Comment this is a reply to. Should be null if it's the top-level comment. Should be the root comment id if it's a top-level comment."
+
            )
+
        )]
        reply_to: Option<CommentId>,
        /// Embeded content.
        #[serde(default, skip_serializing_if = "Vec::is_empty")]
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "Vec<crate::schemars_ext::git::Embed>")
+
        )]
        embeds: Vec<Embed<Uri>>,
    },

@@ -942,20 +956,29 @@ pub enum Action {
    #[serde(rename = "comment.edit")]
    CommentEdit {
        /// Comment being edited.
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        id: CommentId,
        /// New value for the comment body.
        body: String,
        /// New value for the embeds list.
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "Vec<crate::schemars_ext::git::Embed>")
+
        )]
        embeds: Vec<Embed<Uri>>,
    },

    /// Redact a change. Not all changes can be redacted.
    #[serde(rename = "comment.redact")]
-
    CommentRedact { id: CommentId },
+
    CommentRedact {
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
+
        id: CommentId,
+
    },

    /// React to a comment.
    #[serde(rename = "comment.react")]
    CommentReact {
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        id: CommentId,
        reaction: Reaction,
        active: bool,
modified crates/radicle/src/cob/patch.rs
@@ -64,6 +64,11 @@ pub type PatchId = ObjectId;
)]
#[display(inner)]
#[wrap(Deref)]
+
#[cfg_attr(
+
    feature = "schemars",
+
    derive(schemars::JsonSchema),
+
    schemars(with = "crate::schemars_ext::git::Oid")
+
)]
pub struct RevisionId(EntryId);

/// Unique identifier for a patch review.
@@ -84,6 +89,11 @@ pub struct RevisionId(EntryId);
)]
#[display(inner)]
#[wrapper(Deref)]
+
#[cfg_attr(
+
    feature = "schemars",
+
    derive(schemars::JsonSchema),
+
    schemars(with = "crate::schemars_ext::git::Oid")
+
)]
pub struct ReviewId(EntryId);

/// Index of a revision in the revisions list.
@@ -161,6 +171,7 @@ pub enum Error {
/// Patch operation.
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum Action {
    //
    // Actions on patch.
@@ -176,6 +187,7 @@ pub enum Action {
    #[serde(rename = "merge")]
    Merge {
        revision: RevisionId,
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        commit: git::Oid,
    },

@@ -195,6 +207,7 @@ pub enum Action {
    #[serde(rename = "review.redact")]
    ReviewRedact { review: ReviewId },
    #[serde(rename = "review.comment")]
+
    #[serde(rename_all = "camelCase")]
    ReviewComment {
        review: ReviewId,
        body: String,
@@ -204,31 +217,60 @@ pub enum Action {
        /// Should be [`None`] if it's the first comment.
        /// Should be [`Some`] otherwise.
        #[serde(default, skip_serializing_if = "Option::is_none")]
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "Option<crate::schemars_ext::git::Oid>"),
+
            schemars(
+
                description = "Comment this is a reply to. Null if it's the top-level comment, or the root comment id if it's a top-level comment."
+
            )
+
        )]
        reply_to: Option<CommentId>,
        /// Embeded content.
        #[serde(default, skip_serializing_if = "Vec::is_empty")]
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "Vec<crate::schemars_ext::git::Embed>")
+
        )]
        embeds: Vec<Embed<Uri>>,
    },
    #[serde(rename = "review.comment.edit")]
    ReviewCommentEdit {
        review: ReviewId,
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        comment: EntryId,
        body: String,
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "Vec<crate::schemars_ext::git::Embed>")
+
        )]
        embeds: Vec<Embed<Uri>>,
    },
    #[serde(rename = "review.comment.redact")]
-
    ReviewCommentRedact { review: ReviewId, comment: EntryId },
+
    ReviewCommentRedact {
+
        review: ReviewId,
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
+
        comment: EntryId,
+
    },
    #[serde(rename = "review.comment.react")]
    ReviewCommentReact {
        review: ReviewId,
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        comment: EntryId,
        reaction: Reaction,
        active: bool,
    },
    #[serde(rename = "review.comment.resolve")]
-
    ReviewCommentResolve { review: ReviewId, comment: EntryId },
+
    ReviewCommentResolve {
+
        review: ReviewId,
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
+
        comment: EntryId,
+
    },
    #[serde(rename = "review.comment.unresolve")]
-
    ReviewCommentUnresolve { review: ReviewId, comment: EntryId },
+
    ReviewCommentUnresolve {
+
        review: ReviewId,
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
+
        comment: EntryId,
+
    },
    /// React to the review.
    #[serde(rename = "review.react")]
    ReviewReact {
@@ -243,10 +285,18 @@ pub enum Action {
    #[serde(rename = "revision")]
    Revision {
        description: String,
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        base: git::Oid,
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        oid: git::Oid,
        /// Review comments resolved by this revision.
        #[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(
+
                with = "BTreeSet<(crate::schemars_ext::git::Oid, crate::schemars_ext::git::Oid)>"
+
            )
+
        )]
        resolves: BTreeSet<(EntryId, CommentId)>,
    },
    #[serde(rename = "revision.edit")]
@@ -255,6 +305,10 @@ pub enum Action {
        description: String,
        /// Embeded content.
        #[serde(default, skip_serializing_if = "Vec::is_empty")]
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "Vec<crate::schemars_ext::git::Embed>")
+
        )]
        embeds: Vec<Embed<Uri>>,
    },
    /// React to the revision.
@@ -282,29 +336,47 @@ pub enum Action {
        /// Should be [`None`] if it's the top-level comment.
        /// Should be the root [`CommentId`] if it's a top-level comment.
        #[serde(default, skip_serializing_if = "Option::is_none")]
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "Option<crate::schemars_ext::git::Oid>"),
+
            schemars(
+
                description = "Comment this is a reply to. Should be null if it's the top-level comment. Should be the root comment id if it's a top-level comment."
+
            )
+
        )]
        reply_to: Option<CommentId>,
        /// Embeded content.
        #[serde(default, skip_serializing_if = "Vec::is_empty")]
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "Vec<crate::schemars_ext::git::Embed>")
+
        )]
        embeds: Vec<Embed<Uri>>,
    },
    /// Edit a revision comment.
    #[serde(rename = "revision.comment.edit")]
    RevisionCommentEdit {
        revision: RevisionId,
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        comment: CommentId,
        body: String,
+
        #[cfg_attr(
+
            feature = "schemars",
+
            schemars(with = "Vec<crate::schemars_ext::git::Embed>")
+
        )]
        embeds: Vec<Embed<Uri>>,
    },
    /// Redact a revision comment.
    #[serde(rename = "revision.comment.redact")]
    RevisionCommentRedact {
        revision: RevisionId,
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        comment: CommentId,
    },
    /// React to a revision comment.
    #[serde(rename = "revision.comment.react")]
    RevisionCommentReact {
        revision: RevisionId,
+
        #[cfg_attr(feature = "schemars", schemars(with = "crate::schemars_ext::git::Oid"))]
        comment: CommentId,
        reaction: Reaction,
        active: bool,
@@ -387,6 +459,7 @@ impl<R: WriteRepository> Merged<'_, R> {
/// Where a patch is intended to be merged.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum MergeTarget {
    /// Intended for the default branch of the project delegates.
    /// Note that if the delegations change while the patch is open,
@@ -1588,6 +1661,7 @@ impl fmt::Display for Status {
/// A lifecycle operation, resulting in a new state.
#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "status")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum Lifecycle {
    #[default]
    Open,
@@ -1610,6 +1684,7 @@ pub struct Merge {
/// A patch review verdict.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum Verdict {
    /// Accept patch.
    Accept,
modified crates/radicle/src/cob/patch/actions.rs
@@ -16,12 +16,14 @@ use super::{lookup, Error, Patch, ReviewId, Verdict};
/// [`ReviewEdit::run`] will apply the action to the given [`Patch`].
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub enum ReviewEdit {
    /// The initial version of editing a review.
    ///
    /// This allowed editing the `summary`, `verdict`, and `labels` of a
    /// [`Patch`], where the `summary` value was optional.
    #[serde(rename = "review.edit")]
+
    #[schemars(skip)]
    V1(ReviewEditV1),
    /// The latest version of editing a review.
    ///
@@ -154,6 +156,7 @@ impl ReviewEdit {

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema), schemars(inline))]
pub struct ReviewEditV2 {
    review: ReviewId,
    #[serde(default, skip_serializing_if = "String::is_empty")]
@@ -163,11 +166,16 @@ pub struct ReviewEditV2 {
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    labels: Vec<Label>,
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
+
    #[cfg_attr(
+
        feature = "schemars",
+
        schemars(with = "Vec<crate::schemars_ext::git::Embed>")
+
    )]
    embeds: Vec<Embed<Uri>>,
}

#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema), schemars(inline))]
pub struct ReviewEditV1 {
    review: ReviewId,
    #[serde(default, skip_serializing_if = "Option::is_none")]
modified crates/radicle/src/identity/did.rs
@@ -16,6 +16,7 @@ pub enum DidError {

#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
#[serde(into = "String", try_from = "String")]
+
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Did(crypto::PublicKey);

impl Did {
modified crates/radicle/src/schemars_ext.rs
@@ -25,6 +25,14 @@ pub mod crypto {
    ]),
)]
    pub struct PublicKey(String);
+

+
    #[derive(JsonSchema)]
+
    #[schemars(
+
        remote = "::crypto::Signature",
+
        title = "Signature",
+
        description = "A Ed25519 cryptographic signature."
+
    )]
+
    pub struct Signature(String);
}

pub(crate) mod log {
@@ -106,6 +114,16 @@ pub(crate) mod git {
        #[schemars(regex(pattern = r"^([0-9a-fA-F]{64}|[0-9a-fA-F]{40})$"))] String,
    );

+
    #[derive(JsonSchema)]
+
    #[schemars(
+
        remote = "super::radicle_cob::Embed",
+
        description = "An embedded Git object."
+
    )]
+
    pub(crate) struct Embed {
+
        pub name: String,
+
        pub content: String,
+
    }
+

    /// See [`crate::git::RefString`]
    #[derive(JsonSchema)]
    pub(crate) struct RefString(String);