radicle/crefs: Use `GetPayload` to load
Using `GetPayload`, `GetRawCanonicalRefs` can be implemented generically.
This commit is contained in:
parent
5167367918
commit
a2de55cbb9
|
|
@ -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`].
|
||||
|
|
|
|||
|
|
@ -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,40 +955,34 @@ 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;
|
||||
#[derive(Debug, Error)]
|
||||
pub enum RawCanonicalRefsError {
|
||||
#[error(transparent)]
|
||||
Json(#[from] serde_json::Error),
|
||||
}
|
||||
|
||||
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)
|
||||
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);
|
||||
};
|
||||
|
||||
Ok(Some(serde_json::from_value(value.to_owned().into_inner())?))
|
||||
}
|
||||
}
|
||||
|
||||
impl crefs::GetRawCanonicalRefs for RawDoc {
|
||||
type Error = CanonicalRefsError;
|
||||
impl GetRawCanonicalRefs for Doc {}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
impl GetRawCanonicalRefs for RawDoc {}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(clippy::unwrap_used)]
|
||||
|
|
|
|||
|
|
@ -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))))
|
||||
|
|
|
|||
Loading…
Reference in New Issue