Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
radicle: add Op::load method
Merged fintohaps opened 1 year ago

Adds an Op::load helper method for loading an Entry, given its Oid and the store it is stored in.

This can be useful for downstream consumers to inspect operations on COBs given a single Oid, without having to load the entire object and/or graph.

It can also be useful when looking at implementing COB stream primitives.

1 file changed +35 -0 c847a16e 9ef9c5d5
modified radicle/src/cob/op.rs
@@ -3,6 +3,7 @@ use radicle_cob::Manifest;
use serde::Serialize;
use thiserror::Error;

+
use radicle_cob as cob;
use radicle_cob::history::{Entry, EntryId};
use radicle_crypto::PublicKey;

@@ -23,6 +24,23 @@ pub enum OpEncodingError {
    Git(#[from] git2::Error),
}

+
/// Error loading an `Op` from storage.
+
#[derive(Error, Debug)]
+
pub enum LoadError {
+
    #[error("failed to load Op at '{object}': {err}")]
+
    Load {
+
        object: git::Oid,
+
        #[source]
+
        err: Box<dyn std::error::Error + Send + Sync + 'static>,
+
    },
+
    #[error("failed to decode Op at '{object}': {err}")]
+
    Encoding {
+
        object: git::Oid,
+
        #[source]
+
        err: OpEncodingError,
+
    },
+
}
+

/// The `Op` is the operation that is applied onto a state to form a CRDT.
///
/// Everything that can be done in the system is represented by an `Op`.
@@ -93,6 +111,23 @@ impl<A> Op<A> {
            Some(head) => repo.identity_doc_at(head).map(Some),
        }
    }
+

+
    /// Get the `Op` identified by the `id` in the provided `store`.
+
    pub fn load<S>(store: &S, id: git::Oid) -> Result<Self, LoadError>
+
    where
+
        S: cob::change::Storage<
+
            ObjectId = git::Oid,
+
            Parent = git::Oid,
+
            Signatures = crypto::ssh::ExtendedSignature,
+
        >,
+
        for<'de> A: serde::Deserialize<'de>,
+
    {
+
        let entry = store.load(id).map_err(|err| LoadError::Load {
+
            object: id,
+
            err: Box::new(err),
+
        })?;
+
        Op::try_from(&entry).map_err(|err| LoadError::Encoding { object: id, err })
+
    }
}

impl From<Entry> for Op<Vec<u8>> {