cob: Change history type to a string
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
This commit is contained in:
parent
0dc34dc15d
commit
5a47023ac0
|
|
@ -13,7 +13,7 @@ use crate::{
|
|||
change::{self, store, Change},
|
||||
history::entry,
|
||||
signatures::{Signature, Signatures},
|
||||
trailers, HistoryType,
|
||||
trailers,
|
||||
};
|
||||
|
||||
const MANIFEST_BLOB_NAME: &str = "manifest";
|
||||
|
|
@ -154,7 +154,7 @@ impl change::Storage for git2::Repository {
|
|||
|
||||
let tree = self.find_tree(commit.tree())?;
|
||||
let manifest = load_manifest(self, &tree)?;
|
||||
let contents = load_contents(self, &tree, &manifest)?;
|
||||
let contents = load_contents(self, &tree)?;
|
||||
|
||||
Ok(Change {
|
||||
id,
|
||||
|
|
@ -210,20 +210,15 @@ fn load_manifest(
|
|||
fn load_contents(
|
||||
repo: &git2::Repository,
|
||||
tree: &git2::Tree,
|
||||
manifest: &store::Manifest,
|
||||
) -> Result<entry::Contents, error::Load> {
|
||||
Ok(match manifest.history_type {
|
||||
HistoryType::Radicle | HistoryType::Automerge => {
|
||||
let contents_tree_entry = tree
|
||||
.get_name(CHANGE_BLOB_NAME)
|
||||
.ok_or_else(|| error::Load::NoChange(tree.id().into()))?;
|
||||
let contents_object = contents_tree_entry.to_object(repo)?;
|
||||
let contents_blob = contents_object
|
||||
.as_blob()
|
||||
.ok_or_else(|| error::Load::ChangeNotBlob(tree.id().into()))?;
|
||||
contents_blob.content().to_owned()
|
||||
}
|
||||
})
|
||||
let contents_tree_entry = tree
|
||||
.get_name(CHANGE_BLOB_NAME)
|
||||
.ok_or_else(|| error::Load::NoChange(tree.id().into()))?;
|
||||
let contents_object = contents_tree_entry.to_object(repo)?;
|
||||
let contents_blob = contents_object
|
||||
.as_blob()
|
||||
.ok_or_else(|| error::Load::ChangeNotBlob(tree.id().into()))?;
|
||||
Ok(contents_blob.content().to_owned())
|
||||
}
|
||||
|
||||
fn write_commit<O>(
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@ use std::{error::Error, fmt};
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
history::{Contents, HistoryType},
|
||||
signatures, TypeName,
|
||||
};
|
||||
use crate::{history::Contents, signatures, TypeName};
|
||||
|
||||
pub trait Storage {
|
||||
type CreateError: Error + Send + Sync + 'static;
|
||||
|
|
@ -47,7 +44,7 @@ pub trait Storage {
|
|||
|
||||
pub struct Create<Id> {
|
||||
pub typename: TypeName,
|
||||
pub history_type: HistoryType,
|
||||
pub history_type: String,
|
||||
pub tips: Vec<Id>,
|
||||
pub message: String,
|
||||
pub contents: Contents,
|
||||
|
|
@ -126,10 +123,10 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Manifest {
|
||||
/// The name given to the type of collaborative object.
|
||||
pub typename: TypeName,
|
||||
/// The type of history for the collaborative oject.
|
||||
pub history_type: HistoryType,
|
||||
pub history_type: String,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,9 +102,9 @@ impl ChangeGraph {
|
|||
// This is okay because we check that the graph has a root node in
|
||||
// GraphBuilder::build
|
||||
let root = roots.first().unwrap();
|
||||
let typename = {
|
||||
let manifest = {
|
||||
let first_node = &self.graph[*root];
|
||||
first_node.typename().clone()
|
||||
first_node.manifest.clone()
|
||||
};
|
||||
let topo = Topo::new(&self.graph);
|
||||
let items = topo.iter(&self.graph).map(|idx| {
|
||||
|
|
@ -121,7 +121,7 @@ impl ChangeGraph {
|
|||
evaluate(*root_change.id(), &self.graph, items)
|
||||
};
|
||||
CollaborativeObject {
|
||||
typename,
|
||||
manifest,
|
||||
history,
|
||||
id: self.object_id,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,16 +17,6 @@ use crate::pruning_fold;
|
|||
pub mod entry;
|
||||
pub use entry::{Clock, Contents, Entry, EntryId, EntryWithClock};
|
||||
|
||||
#[derive(
|
||||
Clone, Copy, Debug, Default, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
|
||||
)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum HistoryType {
|
||||
#[default]
|
||||
Radicle,
|
||||
Automerge,
|
||||
}
|
||||
|
||||
/// The DAG of changes making up the history of a collaborative object.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct History {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ pub use change::Change;
|
|||
pub mod identity;
|
||||
|
||||
pub mod history;
|
||||
pub use history::{Contents, Entry, History, HistoryType};
|
||||
pub use history::{Contents, Entry, History};
|
||||
|
||||
mod pruning_fold;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use std::collections::BTreeSet;
|
|||
|
||||
use git_ext::Oid;
|
||||
|
||||
use crate::change::store::Manifest;
|
||||
use crate::{change, identity::Identity, Contents, History, ObjectId, TypeName};
|
||||
|
||||
pub mod error;
|
||||
|
|
@ -28,8 +29,8 @@ pub use update::{update, Update};
|
|||
/// A collaborative object
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct CollaborativeObject {
|
||||
/// The typename of this object
|
||||
pub(crate) typename: TypeName,
|
||||
/// The manifest of this object
|
||||
pub(crate) manifest: Manifest,
|
||||
/// The CRDT history we know about for this object
|
||||
pub(crate) history: History,
|
||||
/// The id of the object
|
||||
|
|
@ -46,7 +47,11 @@ impl CollaborativeObject {
|
|||
}
|
||||
|
||||
pub fn typename(&self) -> &TypeName {
|
||||
&self.typename
|
||||
&self.manifest.typename
|
||||
}
|
||||
|
||||
pub fn manifest(&self) -> &Manifest {
|
||||
&self.manifest
|
||||
}
|
||||
|
||||
fn tips(&self) -> BTreeSet<Oid> {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
// This file is part of radicle-link, distributed under the GPLv3 with Radicle
|
||||
// Linking Exception. For full terms see the included LICENSE file.
|
||||
|
||||
use crate::{HistoryType, Store};
|
||||
use crate::Store;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ pub struct Create<Author> {
|
|||
/// The identity of the author for this object's first change.
|
||||
pub author: Option<Author>,
|
||||
/// The type of history that will be used for this object.
|
||||
pub history_type: HistoryType,
|
||||
pub history_type: String,
|
||||
/// The CRDT history to initialize this object with.
|
||||
pub contents: Contents,
|
||||
/// The typename for this object.
|
||||
|
|
@ -25,7 +25,7 @@ impl<Author> Create<Author> {
|
|||
fn create_spec(&self) -> change::Create<git_ext::Oid> {
|
||||
change::Create {
|
||||
typename: self.typename.clone(),
|
||||
history_type: self.history_type,
|
||||
history_type: self.history_type.clone(),
|
||||
tips: Vec::new(),
|
||||
message: self.message.clone(),
|
||||
contents: self.contents.clone(),
|
||||
|
|
@ -101,7 +101,10 @@ where
|
|||
.map_err(|err| error::Create::Refs { err: Box::new(err) })?;
|
||||
|
||||
Ok(CollaborativeObject {
|
||||
typename: args.typename,
|
||||
manifest: Manifest {
|
||||
typename: args.typename,
|
||||
history_type: args.history_type,
|
||||
},
|
||||
history,
|
||||
id: init_change.id().into(),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
// Linking Exception. For full terms see the included LICENSE file.
|
||||
|
||||
use crate::{
|
||||
change, change_graph::ChangeGraph, identity::Identity, CollaborativeObject, Contents,
|
||||
HistoryType, ObjectId, Store, TypeName,
|
||||
change, change_graph::ChangeGraph, identity::Identity, CollaborativeObject, Contents, ObjectId,
|
||||
Store, TypeName,
|
||||
};
|
||||
|
||||
use super::error;
|
||||
|
|
@ -15,7 +15,7 @@ pub struct Update<Author> {
|
|||
/// The identity of the author for the update of this object.
|
||||
pub author: Option<Author>,
|
||||
/// The type of history that will be used for this object.
|
||||
pub history_type: HistoryType,
|
||||
pub history_type: String,
|
||||
/// The CRDT changes to add to the object.
|
||||
pub changes: Contents,
|
||||
/// The object ID of the object to be updated.
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ use quickcheck::Arbitrary;
|
|||
use radicle_crypto::Signer;
|
||||
|
||||
use crate::{
|
||||
create, get, list, object, test::arbitrary::Invalid, update, Create, HistoryType, ObjectId,
|
||||
TypeName, Update,
|
||||
create, get, list, object, test::arbitrary::Invalid, update, Create, ObjectId, TypeName, Update,
|
||||
};
|
||||
|
||||
use super::test;
|
||||
|
|
@ -30,7 +29,7 @@ fn roundtrip() {
|
|||
&proj.identifier(),
|
||||
Create {
|
||||
author: Some(terry),
|
||||
history_type: HistoryType::Automerge,
|
||||
history_type: "test".to_string(),
|
||||
contents: Vec::new(),
|
||||
typename: typename.clone(),
|
||||
message: "creating xyz.rad.issue".to_string(),
|
||||
|
|
@ -63,7 +62,7 @@ fn list_cobs() {
|
|||
&proj.identifier(),
|
||||
Create {
|
||||
author: Some(terry.clone()),
|
||||
history_type: HistoryType::Automerge,
|
||||
history_type: "test".to_string(),
|
||||
contents: b"issue 1".to_vec(),
|
||||
typename: typename.clone(),
|
||||
message: "creating xyz.rad.issue".to_string(),
|
||||
|
|
@ -78,7 +77,7 @@ fn list_cobs() {
|
|||
&proj.identifier(),
|
||||
Create {
|
||||
author: Some(terry),
|
||||
history_type: HistoryType::Automerge,
|
||||
history_type: "test".to_string(),
|
||||
contents: b"issue 2".to_vec(),
|
||||
typename: typename.clone(),
|
||||
message: "commenting xyz.rad.issue".to_string(),
|
||||
|
|
@ -113,7 +112,7 @@ fn update_cob() {
|
|||
&proj.identifier(),
|
||||
Create {
|
||||
author: Some(terry.clone()),
|
||||
history_type: HistoryType::Automerge,
|
||||
history_type: "test".to_string(),
|
||||
contents: Vec::new(),
|
||||
typename: typename.clone(),
|
||||
message: "creating xyz.rad.issue".to_string(),
|
||||
|
|
@ -133,7 +132,7 @@ fn update_cob() {
|
|||
Update {
|
||||
author: Some(terry),
|
||||
changes: b"issue 1".to_vec(),
|
||||
history_type: HistoryType::Automerge,
|
||||
history_type: "test".to_string(),
|
||||
object_id: *cob.id(),
|
||||
typename: typename.clone(),
|
||||
message: "commenting xyz.rad.issue".to_string(),
|
||||
|
|
@ -174,7 +173,7 @@ fn traverse_cobs() {
|
|||
Create {
|
||||
author: Some(terry),
|
||||
contents: b"issue 1".to_vec(),
|
||||
history_type: HistoryType::Automerge,
|
||||
history_type: "test".to_string(),
|
||||
typename: typename.clone(),
|
||||
message: "creating xyz.rad.issue".to_string(),
|
||||
},
|
||||
|
|
@ -197,7 +196,7 @@ fn traverse_cobs() {
|
|||
Update {
|
||||
author: Some(neil),
|
||||
changes: b"issue 2".to_vec(),
|
||||
history_type: HistoryType::Automerge,
|
||||
history_type: "test".to_string(),
|
||||
object_id: *cob.id(),
|
||||
typename,
|
||||
message: "commenting on xyz.rad.issue".to_string(),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ pub mod thread;
|
|||
|
||||
pub use cob::{
|
||||
identity, object::collaboration::error, CollaborativeObject, Contents, Create, Entry, History,
|
||||
HistoryType, ObjectId, TypeName, Update,
|
||||
ObjectId, TypeName, Update,
|
||||
};
|
||||
pub use common::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,13 +8,16 @@ use serde::Serialize;
|
|||
use crate::cob;
|
||||
use crate::cob::common::Author;
|
||||
use crate::cob::CollaborativeObject;
|
||||
use crate::cob::{Create, History, HistoryType, ObjectId, TypeName, Update};
|
||||
use crate::cob::{Create, History, ObjectId, TypeName, Update};
|
||||
use crate::crypto::PublicKey;
|
||||
use crate::git;
|
||||
use crate::identity::project;
|
||||
use crate::prelude::*;
|
||||
use crate::storage::git as storage;
|
||||
|
||||
/// History type for standard radicle COBs.
|
||||
pub const HISTORY_TYPE: &str = "radicle";
|
||||
|
||||
/// A type that can be materialized from an event history.
|
||||
/// All collaborative objects implement this trait.
|
||||
pub trait FromHistory: Sized {
|
||||
|
|
@ -102,7 +105,7 @@ where
|
|||
Update {
|
||||
author: Some(cob::Author::from(*signer.public_key())),
|
||||
object_id,
|
||||
history_type: HistoryType::default(),
|
||||
history_type: HISTORY_TYPE.to_owned(),
|
||||
typename: T::type_name().clone(),
|
||||
message: message.to_owned(),
|
||||
changes,
|
||||
|
|
@ -125,7 +128,7 @@ where
|
|||
&self.project,
|
||||
Create {
|
||||
author: Some(cob::Author::from(*signer.public_key())),
|
||||
history_type: HistoryType::default(),
|
||||
history_type: HISTORY_TYPE.to_owned(),
|
||||
typename: T::type_name().clone(),
|
||||
message: message.to_owned(),
|
||||
contents,
|
||||
|
|
@ -141,6 +144,9 @@ where
|
|||
let cob = cob::get(self.raw, T::type_name(), id)?;
|
||||
|
||||
if let Some(cob) = cob {
|
||||
if cob.manifest().history_type != HISTORY_TYPE {
|
||||
panic!();
|
||||
}
|
||||
let (obj, clock) = T::from_history(cob.history())?;
|
||||
Ok(Some((obj, clock)))
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue