Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
radicle/crefs: Use `GetPayload` to load
Lorenz Leutgeb committed 22 days ago
commit a2de55cbb99ae178f09af61e3acf21192ee62097
parent 5167367
3 files changed +26 -40
modified crates/radicle/src/identity/crefs.rs
@@ -4,19 +4,6 @@ use crate::git::canonical::rules::{RawRules, Rules, ValidationError};

use super::doc::{Delegates, Payload};

-
/// Implemented by any data type or store that can return [`CanonicalRefs`] and
-
/// [`RawCanonicalRefs`].
-
pub trait GetRawCanonicalRefs {
-
    type Error: std::error::Error + Send + Sync + 'static;
-

-
    /// Retrieve the [`RawCanonicalRefs`], returning `Some` if they are
-
    /// present, and `None` if they are absent.
-
    ///
-
    /// [`Self::Error`] is used to return any domain-specific error by the
-
    /// implementing type.
-
    fn raw_canonical_refs(&self) -> Result<Option<RawCanonicalRefs>, Self::Error>;
-
}
-

/// Configuration for canonical references and their rules.
///
/// `RawCanonicalRefs` are verified into [`CanonicalRefs`].
modified crates/radicle/src/identity/doc.rs
@@ -30,7 +30,7 @@ pub use crypto::PublicKey;
pub use radicle_core::repo::*;

use super::CanonicalRefs;
-
use super::crefs::{self, RawCanonicalRefs};
+
use super::crefs::RawCanonicalRefs;

/// Path to the identity document in the identity branch.
pub static PATH: LazyLock<&Path> = LazyLock::new(|| Path::new("radicle.json"));
@@ -256,6 +256,10 @@ impl Payload {
    ) -> Option<&mut serde_json::value::Map<String, serde_json::Value>> {
        self.value.as_object_mut()
    }
+

+
    pub fn into_inner(self) -> serde_json::Value {
+
        self.value
+
    }
}

impl From<serde_json::Value> for Payload {
@@ -774,13 +778,14 @@ impl Doc {
    }

    /// Construct the canonical references for this document.
-
    /// The implementation of [`crefs::RawCanonicalRefs`] is used to
+
    /// The implementation of [`RawCanonicalRefs`] is used to
    /// obtain the payload identified by [`PayloadId::canonical_refs`], if it
    /// exists.
    /// The resulting [`CanonicalRefs`] are constructed by extension with
    /// [`Self::default_branch_rule`].
+
    ///
+
    /// [`RawCanonicalRefs`]: super::crefs::RawCanonicalRefs
    pub fn canonical_refs(&self) -> Result<CanonicalRefs, CanonicalRefsError> {
-
        use crefs::GetRawCanonicalRefs;
        let raw_crefs = self.raw_canonical_refs()?.unwrap_or_default();

        let mut raw_rules = raw_crefs.raw_rules().clone();
@@ -950,41 +955,35 @@ impl Doc {
#[derive(Debug, Error)]
pub enum CanonicalRefsError {
    #[error(transparent)]
-
    Json(#[from] serde_json::Error),
+
    Raw(#[from] RawCanonicalRefsError),
    #[error(transparent)]
    CanonicalRefs(#[from] rules::ValidationError),
    #[error(transparent)]
    DefaultBranch(#[from] DefaultBranchRuleError),
}

-
impl crefs::GetRawCanonicalRefs for Doc {
-
    type Error = CanonicalRefsError;
-

-
    fn raw_canonical_refs(&self) -> Result<Option<RawCanonicalRefs>, Self::Error> {
-
        let value = self.payload.get(&PayloadId::canonical_refs());
-
        let crefs = value
-
            .map(|value| {
-
                serde_json::from_value((**value).clone()).map_err(CanonicalRefsError::from)
-
            })
-
            .transpose()?;
-
        Ok(crefs)
-
    }
+
#[derive(Debug, Error)]
+
pub enum RawCanonicalRefsError {
+
    #[error(transparent)]
+
    Json(#[from] serde_json::Error),
}

-
impl crefs::GetRawCanonicalRefs for RawDoc {
-
    type Error = CanonicalRefsError;
+
pub trait GetRawCanonicalRefs: GetPayload {
+
    /// Retrieve the [`RawCanonicalRefs`] by deserializing from the payload
+
    /// (if present).
+
    fn raw_canonical_refs(&self) -> Result<Option<RawCanonicalRefs>, RawCanonicalRefsError> {
+
        let Some(value) = self.get_payload(&PayloadId::canonical_refs()) else {
+
            return Ok(None);
+
        };

-
    fn raw_canonical_refs(&self) -> Result<Option<RawCanonicalRefs>, Self::Error> {
-
        let value = self.payload.get(&PayloadId::canonical_refs());
-
        let crefs = value
-
            .map(|value| {
-
                serde_json::from_value((**value).clone()).map_err(CanonicalRefsError::from)
-
            })
-
            .transpose()?;
-
        Ok(crefs)
+
        Ok(Some(serde_json::from_value(value.to_owned().into_inner())?))
    }
}

+
impl GetRawCanonicalRefs for Doc {}
+

+
impl GetRawCanonicalRefs for RawDoc {}
+

#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod test {
modified crates/radicle/src/identity/doc/update.rs
@@ -211,7 +211,7 @@ pub fn verify(raw: RawDoc) -> Result<Doc, error::DocVerification> {
    // Ensure that if we have canonical reference rules and a project, that no
    // rule exists for the default branch. This rule must be synthesized when
    // constructing the canonical reference rules.
-
    use super::crefs::GetRawCanonicalRefs as _;
+
    use super::GetRawCanonicalRefs as _;
    match raw
        .raw_canonical_refs()
        .map(|rcrefs| rcrefs.and_then(|c| project.map(|p| (c, p))))