cob: Parametrize `cob::Store` with repository type
The additional flexibility in choosing a backend for the COB store will allow things like "draft" COBs that are stored in a different location, without changing much of the logic.
This commit is contained in:
parent
45ccbde226
commit
c9162121b0
|
|
@ -14,7 +14,7 @@ use radicle::node::{AliasStore, Handle};
|
|||
use radicle::prelude::Did;
|
||||
use radicle::profile;
|
||||
use radicle::storage;
|
||||
use radicle::storage::WriteStorage;
|
||||
use radicle::storage::{WriteRepository, WriteStorage};
|
||||
use radicle::{cob, Node};
|
||||
use radicle_term::table::TableOptions;
|
||||
use radicle_term::{Paint, Table, VStack};
|
||||
|
|
@ -359,8 +359,8 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn list(
|
||||
issues: &Issues,
|
||||
fn list<R: WriteRepository + cob::Store>(
|
||||
issues: &Issues<R>,
|
||||
assigned: &Option<Assigned>,
|
||||
state: &Option<State>,
|
||||
profile: &profile::Profile,
|
||||
|
|
@ -544,12 +544,12 @@ fn prompt_issue(
|
|||
Ok(Some((meta, description)))
|
||||
}
|
||||
|
||||
fn open<G: Signer>(
|
||||
fn open<R: WriteRepository + cob::Store, G: Signer>(
|
||||
title: Option<String>,
|
||||
description: Option<String>,
|
||||
tags: Vec<Tag>,
|
||||
options: &Options,
|
||||
issues: &mut Issues,
|
||||
issues: &mut Issues<R>,
|
||||
signer: &G,
|
||||
) -> anyhow::Result<()> {
|
||||
let Some((meta, description)) = prompt_issue(
|
||||
|
|
@ -579,8 +579,8 @@ fn open<G: Signer>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn edit<G: radicle::crypto::Signer>(
|
||||
issues: &mut issue::Issues,
|
||||
fn edit<R: WriteRepository + cob::Store, G: radicle::crypto::Signer>(
|
||||
issues: &mut issue::Issues<R>,
|
||||
signer: &G,
|
||||
repo: &storage::git::Repository,
|
||||
id: Rev,
|
||||
|
|
|
|||
|
|
@ -116,9 +116,9 @@ mod tests;
|
|||
/// [`git2::Repository`]. It is expected that the underlying storage
|
||||
/// for `object::Storage` will also be `git2::Repository`, but if not
|
||||
/// please open an issue to change the definition of `Store` :)
|
||||
pub trait Store
|
||||
pub trait Store<I = crypto::PublicKey>
|
||||
where
|
||||
Self: object::Storage
|
||||
Self: object::Storage<Identifier = I>
|
||||
+ change::Storage<
|
||||
StoreError = git::change::error::Create,
|
||||
LoadError = git::change::error::Load,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ impl Create {
|
|||
///
|
||||
/// The `args` are the metadata for this [`CollaborativeObject`]. See
|
||||
/// [`Create`] for further information.
|
||||
pub fn create<S, G>(
|
||||
pub fn create<S, I, G>(
|
||||
storage: &S,
|
||||
signer: &G,
|
||||
resource: Oid,
|
||||
|
|
@ -57,7 +57,7 @@ pub fn create<S, G>(
|
|||
args: Create,
|
||||
) -> Result<CollaborativeObject, error::Create>
|
||||
where
|
||||
S: Store,
|
||||
S: Store<I>,
|
||||
G: crypto::Signer,
|
||||
{
|
||||
let Create { ref typename, .. } = &args;
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ use super::error;
|
|||
/// The `typename` is the type of object to be found, while the
|
||||
/// `object_id` is the identifier for the particular object under that
|
||||
/// type.
|
||||
pub fn get<S>(
|
||||
pub fn get<S, I>(
|
||||
storage: &S,
|
||||
typename: &TypeName,
|
||||
oid: &ObjectId,
|
||||
) -> Result<Option<CollaborativeObject>, error::Retrieve>
|
||||
where
|
||||
S: Store,
|
||||
S: Store<I>,
|
||||
{
|
||||
let tip_refs = storage
|
||||
.objects(typename, oid)
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ use super::error;
|
|||
/// [`Store`] for further information.
|
||||
///
|
||||
/// The `typename` is the type of objects to be listed.
|
||||
pub fn list<S>(
|
||||
pub fn list<S, I>(
|
||||
storage: &S,
|
||||
typename: &TypeName,
|
||||
) -> Result<Vec<CollaborativeObject>, error::Retrieve>
|
||||
where
|
||||
S: Store,
|
||||
S: Store<I>,
|
||||
{
|
||||
let references = storage
|
||||
.types(typename)
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ use super::error;
|
|||
/// The `typename` is the type of object to be found, while the
|
||||
/// `object_id` is the identifier for the particular object under that
|
||||
/// type.
|
||||
pub fn remove<S>(
|
||||
pub fn remove<S, I>(
|
||||
storage: &S,
|
||||
identifier: &S::Identifier,
|
||||
typename: &TypeName,
|
||||
oid: &ObjectId,
|
||||
) -> Result<(), error::Remove>
|
||||
where
|
||||
S: Store,
|
||||
S: Store<I>,
|
||||
{
|
||||
storage
|
||||
.remove(identifier, typename, oid)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ pub struct Update {
|
|||
///
|
||||
/// The `args` are the metadata for this [`CollaborativeObject`]
|
||||
/// udpate. See [`Update`] for further information.
|
||||
pub fn update<S, G>(
|
||||
pub fn update<S, I, G>(
|
||||
storage: &S,
|
||||
signer: &G,
|
||||
resource: Oid,
|
||||
|
|
@ -58,7 +58,7 @@ pub fn update<S, G>(
|
|||
args: Update,
|
||||
) -> Result<Updated, error::Update>
|
||||
where
|
||||
S: Store,
|
||||
S: Store<I>,
|
||||
G: crypto::Signer,
|
||||
{
|
||||
let Update {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use crate::{ObjectId, TypeName};
|
|||
|
||||
/// The [`Reference`]s that refer to the commits that make up a
|
||||
/// [`crate::CollaborativeObject`].
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Objects(Vec<Reference>);
|
||||
|
||||
impl Objects {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ impl Storage {
|
|||
}
|
||||
}
|
||||
|
||||
impl Store for Storage {}
|
||||
impl Store<Urn> for Storage {}
|
||||
|
||||
impl change::Storage for Storage {
|
||||
type StoreError = <git2::Repository as change::Storage>::StoreError;
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ pub mod thread;
|
|||
#[cfg(test)]
|
||||
pub mod test;
|
||||
|
||||
pub use cob::{create, get, list, remove, update};
|
||||
pub use cob::{
|
||||
history::EntryId, object::collaboration::error, CollaborativeObject, Contents, Create, Entry,
|
||||
History, ObjectId, TypeName, Update, Updated,
|
||||
change, history::EntryId, object, object::collaboration::error, CollaborativeObject, Contents,
|
||||
Create, Entry, History, ObjectId, Store, TypeName, Update, Updated,
|
||||
};
|
||||
pub use cob::{create, get, list, remove, update};
|
||||
pub use common::*;
|
||||
pub use op::{ActorId, Op};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use crate::{
|
|||
},
|
||||
identity::{doc::DocError, Did, Identity, IdentityError},
|
||||
prelude::{Doc, ReadRepository},
|
||||
storage::{git as storage, RemoteId, WriteRepository},
|
||||
storage::{RemoteId, WriteRepository},
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
|
@ -561,20 +561,23 @@ impl store::Transaction<Proposal> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ProposalMut<'a, 'g> {
|
||||
pub struct ProposalMut<'a, 'g, R> {
|
||||
pub id: ObjectId,
|
||||
|
||||
proposal: Proposal,
|
||||
clock: clock::Lamport,
|
||||
store: &'g mut Proposals<'a>,
|
||||
store: &'g mut Proposals<'a, R>,
|
||||
}
|
||||
|
||||
impl<'a, 'g> ProposalMut<'a, 'g> {
|
||||
impl<'a, 'g, R> ProposalMut<'a, 'g, R>
|
||||
where
|
||||
R: WriteRepository + cob::Store,
|
||||
{
|
||||
pub fn new(
|
||||
id: ObjectId,
|
||||
proposal: Proposal,
|
||||
clock: clock::Lamport,
|
||||
store: &'g mut Proposals<'a>,
|
||||
store: &'g mut Proposals<'a, R>,
|
||||
) -> Self {
|
||||
Self {
|
||||
id,
|
||||
|
|
@ -672,7 +675,7 @@ impl<'a, 'g> ProposalMut<'a, 'g> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'g> Deref for ProposalMut<'a, 'g> {
|
||||
impl<'a, 'g, R> Deref for ProposalMut<'a, 'g, R> {
|
||||
type Target = Proposal;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
|
@ -680,21 +683,24 @@ impl<'a, 'g> Deref for ProposalMut<'a, 'g> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Proposals<'a> {
|
||||
raw: store::Store<'a, Proposal>,
|
||||
pub struct Proposals<'a, R> {
|
||||
raw: store::Store<'a, Proposal, R>,
|
||||
}
|
||||
|
||||
impl<'a> Deref for Proposals<'a> {
|
||||
type Target = store::Store<'a, Proposal>;
|
||||
impl<'a, R> Deref for Proposals<'a, R> {
|
||||
type Target = store::Store<'a, Proposal, R>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.raw
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Proposals<'a> {
|
||||
impl<'a, R: WriteRepository> Proposals<'a, R>
|
||||
where
|
||||
R: WriteRepository + cob::Store,
|
||||
{
|
||||
/// Open a proposals store.
|
||||
pub fn open(repository: &'a storage::Repository) -> Result<Self, store::Error> {
|
||||
pub fn open(repository: &'a R) -> Result<Self, store::Error> {
|
||||
let raw = store::Store::open(repository)?;
|
||||
|
||||
Ok(Self { raw })
|
||||
|
|
@ -708,7 +714,7 @@ impl<'a> Proposals<'a> {
|
|||
current: impl Into<Oid>,
|
||||
proposed: Doc<Verified>,
|
||||
signer: &G,
|
||||
) -> Result<ProposalMut<'a, 'g>, Error> {
|
||||
) -> Result<ProposalMut<'a, 'g, R>, Error> {
|
||||
let (id, proposal, clock) =
|
||||
Transaction::initial("Create proposal", &mut self.raw, signer, |tx| {
|
||||
tx.revision(current.into(), proposed)?;
|
||||
|
|
@ -728,7 +734,10 @@ impl<'a> Proposals<'a> {
|
|||
}
|
||||
|
||||
/// Get a proposal mutably.
|
||||
pub fn get_mut<'g>(&'g mut self, id: &ObjectId) -> Result<ProposalMut<'a, 'g>, store::Error> {
|
||||
pub fn get_mut<'g>(
|
||||
&'g mut self,
|
||||
id: &ObjectId,
|
||||
) -> Result<ProposalMut<'a, 'g, R>, store::Error> {
|
||||
let (proposal, clock) = self
|
||||
.raw
|
||||
.get(id)?
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use crate::cob::thread::{CommentId, Thread};
|
|||
use crate::cob::{store, ActorId, EntryId, ObjectId, TypeName};
|
||||
use crate::crypto::Signer;
|
||||
use crate::prelude::{Did, ReadRepository};
|
||||
use crate::storage::git as storage;
|
||||
use crate::storage::WriteRepository;
|
||||
|
||||
/// Issue operation.
|
||||
pub type Op = cob::Op<Action>;
|
||||
|
|
@ -331,14 +331,17 @@ impl store::Transaction<Issue> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct IssueMut<'a, 'g> {
|
||||
pub struct IssueMut<'a, 'g, R> {
|
||||
id: ObjectId,
|
||||
clock: clock::Lamport,
|
||||
issue: Issue,
|
||||
store: &'g mut Issues<'a>,
|
||||
store: &'g mut Issues<'a, R>,
|
||||
}
|
||||
|
||||
impl<'a, 'g> IssueMut<'a, 'g> {
|
||||
impl<'a, 'g, R> IssueMut<'a, 'g, R>
|
||||
where
|
||||
R: WriteRepository + cob::Store,
|
||||
{
|
||||
/// Get the issue id.
|
||||
pub fn id(&self) -> &ObjectId {
|
||||
&self.id
|
||||
|
|
@ -457,7 +460,7 @@ impl<'a, 'g> IssueMut<'a, 'g> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'g> Deref for IssueMut<'a, 'g> {
|
||||
impl<'a, 'g, R> Deref for IssueMut<'a, 'g, R> {
|
||||
type Target = Issue;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
|
@ -465,12 +468,12 @@ impl<'a, 'g> Deref for IssueMut<'a, 'g> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Issues<'a> {
|
||||
raw: store::Store<'a, Issue>,
|
||||
pub struct Issues<'a, R> {
|
||||
raw: store::Store<'a, Issue, R>,
|
||||
}
|
||||
|
||||
impl<'a> Deref for Issues<'a> {
|
||||
type Target = store::Store<'a, Issue>;
|
||||
impl<'a, R> Deref for Issues<'a, R> {
|
||||
type Target = store::Store<'a, Issue, R>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.raw
|
||||
|
|
@ -485,9 +488,12 @@ pub struct IssueCounts {
|
|||
pub closed: usize,
|
||||
}
|
||||
|
||||
impl<'a> Issues<'a> {
|
||||
impl<'a, R: WriteRepository> Issues<'a, R>
|
||||
where
|
||||
R: ReadRepository + cob::Store,
|
||||
{
|
||||
/// Open an issues store.
|
||||
pub fn open(repository: &'a storage::Repository) -> Result<Self, store::Error> {
|
||||
pub fn open(repository: &'a R) -> Result<Self, store::Error> {
|
||||
let raw = store::Store::open(repository)?;
|
||||
|
||||
Ok(Self { raw })
|
||||
|
|
@ -499,7 +505,7 @@ impl<'a> Issues<'a> {
|
|||
}
|
||||
|
||||
/// Get an issue mutably.
|
||||
pub fn get_mut<'g>(&'g mut self, id: &ObjectId) -> Result<IssueMut<'a, 'g>, store::Error> {
|
||||
pub fn get_mut<'g>(&'g mut self, id: &ObjectId) -> Result<IssueMut<'a, 'g, R>, store::Error> {
|
||||
let (issue, clock) = self
|
||||
.raw
|
||||
.get(id)?
|
||||
|
|
@ -521,7 +527,7 @@ impl<'a> Issues<'a> {
|
|||
tags: &[Tag],
|
||||
assignees: &[ActorId],
|
||||
signer: &G,
|
||||
) -> Result<IssueMut<'a, 'g>, Error> {
|
||||
) -> Result<IssueMut<'a, 'g, R>, Error> {
|
||||
let (id, issue, clock) =
|
||||
Transaction::initial("Create issue", &mut self.raw, signer, |tx| {
|
||||
tx.thread(description)?;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ use crate::identity;
|
|||
use crate::identity::doc::DocError;
|
||||
use crate::identity::PayloadError;
|
||||
use crate::prelude::*;
|
||||
use crate::storage::git as storage;
|
||||
|
||||
/// The logical clock we use to order operations to patches.
|
||||
pub use clock::Lamport as Clock;
|
||||
|
|
@ -1143,20 +1142,23 @@ impl store::Transaction<Patch> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct PatchMut<'a, 'g> {
|
||||
pub struct PatchMut<'a, 'g, R> {
|
||||
pub id: ObjectId,
|
||||
|
||||
patch: Patch,
|
||||
clock: clock::Lamport,
|
||||
store: &'g mut Patches<'a>,
|
||||
store: &'g mut Patches<'a, R>,
|
||||
}
|
||||
|
||||
impl<'a, 'g> PatchMut<'a, 'g> {
|
||||
impl<'a, 'g, R> PatchMut<'a, 'g, R>
|
||||
where
|
||||
R: WriteRepository + cob::Store,
|
||||
{
|
||||
pub fn new(
|
||||
id: ObjectId,
|
||||
patch: Patch,
|
||||
clock: clock::Lamport,
|
||||
store: &'g mut Patches<'a>,
|
||||
store: &'g mut Patches<'a, R>,
|
||||
) -> Self {
|
||||
Self {
|
||||
id,
|
||||
|
|
@ -1358,7 +1360,7 @@ impl<'a, 'g> PatchMut<'a, 'g> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'g> Deref for PatchMut<'a, 'g> {
|
||||
impl<'a, 'g, R> Deref for PatchMut<'a, 'g, R> {
|
||||
type Target = Patch;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
|
|
@ -1376,21 +1378,24 @@ pub struct PatchCounts {
|
|||
pub merged: usize,
|
||||
}
|
||||
|
||||
pub struct Patches<'a> {
|
||||
raw: store::Store<'a, Patch>,
|
||||
pub struct Patches<'a, R> {
|
||||
raw: store::Store<'a, Patch, R>,
|
||||
}
|
||||
|
||||
impl<'a> Deref for Patches<'a> {
|
||||
type Target = store::Store<'a, Patch>;
|
||||
impl<'a, R> Deref for Patches<'a, R> {
|
||||
type Target = store::Store<'a, Patch, R>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.raw
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Patches<'a> {
|
||||
impl<'a, R> Patches<'a, R>
|
||||
where
|
||||
R: WriteRepository + cob::Store,
|
||||
{
|
||||
/// Open an patches store.
|
||||
pub fn open(repository: &'a storage::Repository) -> Result<Self, store::Error> {
|
||||
pub fn open(repository: &'a R) -> Result<Self, store::Error> {
|
||||
let raw = store::Store::open(repository)?;
|
||||
|
||||
Ok(Self { raw })
|
||||
|
|
@ -1406,7 +1411,7 @@ impl<'a> Patches<'a> {
|
|||
oid: impl Into<git::Oid>,
|
||||
tags: &[Tag],
|
||||
signer: &G,
|
||||
) -> Result<PatchMut<'a, 'g>, Error> {
|
||||
) -> Result<PatchMut<'a, 'g, R>, Error> {
|
||||
self._create(
|
||||
title,
|
||||
description,
|
||||
|
|
@ -1429,7 +1434,7 @@ impl<'a> Patches<'a> {
|
|||
oid: impl Into<git::Oid>,
|
||||
tags: &[Tag],
|
||||
signer: &G,
|
||||
) -> Result<PatchMut<'a, 'g>, Error> {
|
||||
) -> Result<PatchMut<'a, 'g, R>, Error> {
|
||||
self._create(
|
||||
title,
|
||||
description,
|
||||
|
|
@ -1484,7 +1489,7 @@ impl<'a> Patches<'a> {
|
|||
}
|
||||
|
||||
/// Get a patch mutably.
|
||||
pub fn get_mut<'g>(&'g mut self, id: &ObjectId) -> Result<PatchMut<'a, 'g>, store::Error> {
|
||||
pub fn get_mut<'g>(&'g mut self, id: &ObjectId) -> Result<PatchMut<'a, 'g, R>, store::Error> {
|
||||
let (patch, clock) = self
|
||||
.raw
|
||||
.get(id)?
|
||||
|
|
@ -1531,7 +1536,7 @@ impl<'a> Patches<'a> {
|
|||
tags: &[Tag],
|
||||
state: State,
|
||||
signer: &G,
|
||||
) -> Result<PatchMut<'a, 'g>, Error> {
|
||||
) -> Result<PatchMut<'a, 'g, R>, Error> {
|
||||
let (id, patch, clock) =
|
||||
Transaction::initial("Create patch", &mut self.raw, signer, |tx| {
|
||||
tx.revision(description, base, oid)?;
|
||||
|
|
|
|||
|
|
@ -128,21 +128,21 @@ impl Error {
|
|||
}
|
||||
|
||||
/// Storage for collaborative objects of a specific type `T` in a single repository.
|
||||
pub struct Store<'a, T> {
|
||||
pub struct Store<'a, T, R> {
|
||||
identity: git::Oid,
|
||||
repo: &'a storage::Repository,
|
||||
repo: &'a R,
|
||||
witness: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'a, T> AsRef<storage::Repository> for Store<'a, T> {
|
||||
fn as_ref(&self) -> &storage::Repository {
|
||||
impl<'a, T, R> AsRef<R> for Store<'a, T, R> {
|
||||
fn as_ref(&self) -> &R {
|
||||
self.repo
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Store<'a, T> {
|
||||
impl<'a, T, R: ReadRepository> Store<'a, T, R> {
|
||||
/// Open a new generic store.
|
||||
pub fn open(repo: &'a storage::Repository) -> Result<Self, Error> {
|
||||
pub fn open(repo: &'a R) -> Result<Self, Error> {
|
||||
let identity = repo.identity()?;
|
||||
|
||||
Ok(Self {
|
||||
|
|
@ -153,8 +153,10 @@ impl<'a, T> Store<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: FromHistory> Store<'a, T>
|
||||
impl<'a, T, R> Store<'a, T, R>
|
||||
where
|
||||
R: WriteRepository + cob::Store,
|
||||
T: FromHistory,
|
||||
T::Action: Serialize,
|
||||
{
|
||||
/// Update an object.
|
||||
|
|
@ -299,15 +301,16 @@ impl<T: FromHistory> Transaction<T> {
|
|||
}
|
||||
|
||||
/// Create a new transaction to be used as the initial set of operations for a COB.
|
||||
pub fn initial<G, F>(
|
||||
pub fn initial<R, G, F>(
|
||||
message: &str,
|
||||
store: &mut Store<T>,
|
||||
store: &mut Store<T, R>,
|
||||
signer: &G,
|
||||
operations: F,
|
||||
) -> Result<(ObjectId, T, Lamport), Error>
|
||||
where
|
||||
G: Signer,
|
||||
F: FnOnce(&mut Self) -> Result<(), Error>,
|
||||
R: WriteRepository + cob::Store,
|
||||
T::Action: Serialize + Clone,
|
||||
{
|
||||
let actor = *signer.public_key();
|
||||
|
|
@ -339,14 +342,15 @@ impl<T: FromHistory> Transaction<T> {
|
|||
/// Commit transaction.
|
||||
///
|
||||
/// Returns a list of operations that can be applied onto an in-memory CRDT.
|
||||
pub fn commit<G: Signer>(
|
||||
pub fn commit<R, G: Signer>(
|
||||
mut self,
|
||||
msg: &str,
|
||||
id: ObjectId,
|
||||
store: &mut Store<T>,
|
||||
store: &mut Store<T, R>,
|
||||
signer: &G,
|
||||
) -> Result<(Vec<cob::Op<T::Action>>, Lamport, EntryId), Error>
|
||||
where
|
||||
R: WriteRepository + cob::Store,
|
||||
T::Action: Serialize + Clone,
|
||||
{
|
||||
let actions = NonEmpty::from_vec(self.actions)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use crate::git::{refspec::Refspec, PatternString, Qualified, RefError, RefString
|
|||
use crate::identity;
|
||||
use crate::identity::doc::DocError;
|
||||
use crate::identity::Did;
|
||||
use crate::identity::{Id, IdentityError};
|
||||
use crate::identity::{Id, Identity, IdentityError};
|
||||
use crate::storage::git::NAMESPACES_GLOB;
|
||||
use crate::storage::refs::Refs;
|
||||
|
||||
|
|
@ -319,7 +319,7 @@ pub trait WriteStorage: ReadStorage {
|
|||
}
|
||||
|
||||
/// Allows read-only access to a repository.
|
||||
pub trait ReadRepository {
|
||||
pub trait ReadRepository: Sized {
|
||||
/// Return the repository id.
|
||||
fn id(&self) -> Id;
|
||||
|
||||
|
|
@ -368,6 +368,13 @@ pub trait ReadRepository {
|
|||
/// `rad/id` using [`ReadRepository::canonical_identity_head`].
|
||||
fn identity_head(&self) -> Result<Oid, IdentityError>;
|
||||
|
||||
/// Load the canonical identity.
|
||||
fn identity(&self) -> Result<Identity<Oid>, IdentityError> {
|
||||
let head = self.identity_head()?;
|
||||
|
||||
Identity::load_at(head, self)
|
||||
}
|
||||
|
||||
/// Compute the canonical `rad/id` of this repository.
|
||||
///
|
||||
/// Ignores any existing `rad/id` reference.
|
||||
|
|
|
|||
|
|
@ -291,12 +291,6 @@ impl Repository {
|
|||
Identity::load(remote, self)
|
||||
}
|
||||
|
||||
pub fn identity(&self) -> Result<Identity<Oid>, IdentityError> {
|
||||
let head = self.identity_head()?;
|
||||
|
||||
Identity::load_at(head, self)
|
||||
}
|
||||
|
||||
/// Get the canonical project information.
|
||||
pub fn project(&self) -> Result<Project, IdentityError> {
|
||||
let head = self.identity_head()?;
|
||||
|
|
|
|||
Loading…
Reference in New Issue