From 34939253f77c85bcb055a0d9deba6bd08e7f1b39 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Tue, 1 Jul 2025 16:52:21 +0200 Subject: [PATCH] radicle: improve reviews MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `Review::summary` was limited in behaviour, since it was only an `Option`. The field is now changed to `NonEmpty` so that it can enable an edit history, as well as being able to supply embeds as part of the text. `Reactions` are also introduced to `Review` and, necessarily, introducing an `Action::ReviewReact`. Note that some machinery was added under `actions` and `encoding` to enable backwards-compatibility. For `actions`, a new `ReviewEdit` is introduced to keep track of the different versions of editing actions – supporting the old actions while also introducing the new variant. For `encoding`, the machinery exploits the fact that an `Option` can be converted into a `NonEmpty` given that an `ActorId` and `Timestamp` are available, and that `None` can be converted into an empty string. The struct `patch::Review` now deserializes via this `encoding::review::Review` type and, importantly, preserves backwards-compatibility. --- Cargo.lock | 28 ++ crates/radicle/Cargo.toml | 1 + crates/radicle/src/cob/patch.rs | 149 ++++++---- crates/radicle/src/cob/patch/actions.rs | 180 +++++++++++++ crates/radicle/src/cob/patch/encoding.rs | 6 + .../radicle/src/cob/patch/encoding/review.rs | 254 ++++++++++++++++++ 6 files changed, 573 insertions(+), 45 deletions(-) create mode 100644 crates/radicle/src/cob/patch/actions.rs create mode 100644 crates/radicle/src/cob/patch/encoding.rs create mode 100644 crates/radicle/src/cob/patch/encoding/review.rs diff --git a/Cargo.lock b/Cargo.lock index 119495a2..c640af10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -802,6 +802,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "erased-serde" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" +dependencies = [ + "serde", + "typeid", +] + [[package]] name = "errno" version = "0.3.13" @@ -2471,6 +2481,7 @@ dependencies = [ "radicle-ssh", "schemars", "serde", + "serde-untagged", "serde_json", "siphasher 1.0.1", "sqlite", @@ -3012,6 +3023,17 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-untagged" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "299d9c19d7d466db4ab10addd5703e4c615dec2a5a16dbbafe191045e87ee66e" +dependencies = [ + "erased-serde", + "serde", + "typeid", +] + [[package]] name = "serde_derive" version = "1.0.219" @@ -3603,6 +3625,12 @@ dependencies = [ "tree-sitter-language", ] +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "typenum" version = "1.17.0" diff --git a/crates/radicle/Cargo.toml b/crates/radicle/Cargo.toml index 38562b02..acb4ba82 100644 --- a/crates/radicle/Cargo.toml +++ b/crates/radicle/Cargo.toml @@ -37,6 +37,7 @@ radicle-ssh = { workspace = true } schemars = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true, features = ["preserve_order"] } +serde-untagged = "0.1.7" siphasher = "1.0.0" sqlite = { workspace = true, features = ["bundled"] } tempfile = { workspace = true } diff --git a/crates/radicle/src/cob/patch.rs b/crates/radicle/src/cob/patch.rs index fc224a0c..8bfbe27a 100644 --- a/crates/radicle/src/cob/patch.rs +++ b/crates/radicle/src/cob/patch.rs @@ -1,5 +1,10 @@ pub mod cache; +mod actions; +pub use actions::ReviewEdit; + +mod encoding; + use std::collections::btree_map; use std::collections::{BTreeMap, BTreeSet, HashMap}; use std::fmt; @@ -187,16 +192,6 @@ pub enum Action { #[serde(default, skip_serializing_if = "Vec::is_empty")] labels: Vec