radicle: add Op::load method
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.
This commit is contained in:
parent
c847a16e14
commit
9ef9c5d59a
|
|
@ -3,6 +3,7 @@ use radicle_cob::Manifest;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use radicle_cob as cob;
|
||||||
use radicle_cob::history::{Entry, EntryId};
|
use radicle_cob::history::{Entry, EntryId};
|
||||||
use radicle_crypto::PublicKey;
|
use radicle_crypto::PublicKey;
|
||||||
|
|
||||||
|
|
@ -23,6 +24,23 @@ pub enum OpEncodingError {
|
||||||
Git(#[from] git2::Error),
|
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.
|
/// 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`.
|
/// 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),
|
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>> {
|
impl From<Entry> for Op<Vec<u8>> {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue