radicle-cob: simplify Objects and remove identifier
Objects does not need to be separated by `local` and `remotes`, it uses `iter` internally, so all references are used regardless. Simplify Objects by having it be a simple vector of references. This also means that the `identifier` is not needed. This was only required to identify the local reference, so it can now be removed. Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com> X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
parent
d6416c9be1
commit
0bd213d15a
|
|
@ -13,15 +13,11 @@ use super::error;
|
|||
/// [`crate::Change`]s at content-addressable locations. Please see
|
||||
/// [`Store`] for further information.
|
||||
///
|
||||
/// The `identifier` is a unqiue id that is passed through to the
|
||||
/// [`crate::object::Storage`].
|
||||
///
|
||||
/// 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>(
|
||||
storage: &S,
|
||||
identifier: &S::Identifier,
|
||||
typename: &TypeName,
|
||||
oid: &ObjectId,
|
||||
) -> Result<Option<CollaborativeObject>, error::Retrieve>
|
||||
|
|
@ -29,7 +25,7 @@ where
|
|||
S: Store,
|
||||
{
|
||||
let tip_refs = storage
|
||||
.objects(identifier, typename, oid)
|
||||
.objects(typename, oid)
|
||||
.map_err(|err| error::Retrieve::Refs { err: Box::new(err) })?;
|
||||
Ok(ChangeGraph::load(storage, tip_refs.iter(), typename, oid).map(|graph| graph.evaluate()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,14 +38,10 @@ pub struct ChangeGraphInfo {
|
|||
/// [`crate::Change`]s at content-addressable locations. Please see
|
||||
/// [`Store`] for further information.
|
||||
///
|
||||
/// The `resource` is the parent of this object, for example a
|
||||
/// software project.
|
||||
///
|
||||
/// The `typename` is the type of object to be found, while the `oid`
|
||||
/// is the identifier for the particular object under that type.
|
||||
pub fn changegraph<S>(
|
||||
storage: &S,
|
||||
identifier: &S::Identifier,
|
||||
typename: &TypeName,
|
||||
oid: &ObjectId,
|
||||
) -> Result<Option<ChangeGraphInfo>, error::Retrieve>
|
||||
|
|
@ -53,7 +49,7 @@ where
|
|||
S: Store,
|
||||
{
|
||||
let tip_refs = storage
|
||||
.objects(identifier, typename, oid)
|
||||
.objects(typename, oid)
|
||||
.map_err(|err| error::Retrieve::Refs { err: Box::new(err) })?;
|
||||
Ok(
|
||||
ChangeGraph::load(storage, tip_refs.iter(), typename, oid).map(|graph| ChangeGraphInfo {
|
||||
|
|
|
|||
|
|
@ -13,20 +13,16 @@ use super::error;
|
|||
/// [`crate::Change`]s at content-addressable locations. Please see
|
||||
/// [`Store`] for further information.
|
||||
///
|
||||
/// The `identifier` is a unqiue id that is passed through to the
|
||||
/// [`crate::object::Storage`].
|
||||
///
|
||||
/// The `typename` is the type of objects to listed.
|
||||
pub fn list<S>(
|
||||
storage: &S,
|
||||
identifier: &S::Identifier,
|
||||
typename: &TypeName,
|
||||
) -> Result<Vec<CollaborativeObject>, error::Retrieve>
|
||||
where
|
||||
S: Store,
|
||||
{
|
||||
let references = storage
|
||||
.types(identifier, typename)
|
||||
.types(typename)
|
||||
.map_err(|err| error::Retrieve::Refs { err: Box::new(err) })?;
|
||||
log::trace!("loaded {} references", references.len());
|
||||
let mut result = Vec::new();
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ where
|
|||
};
|
||||
|
||||
let existing_refs = storage
|
||||
.objects(identifier, typename, &object_id)
|
||||
.objects(typename, &object_id)
|
||||
.map_err(|err| error::Update::Refs { err: Box::new(err) })?;
|
||||
|
||||
let mut object = ChangeGraph::load(storage, existing_refs.iter(), typename, &object_id)
|
||||
|
|
|
|||
|
|
@ -14,20 +14,27 @@ use crate::{ObjectId, TypeName};
|
|||
/// The [`Reference`]s that refer to the commits that make up a
|
||||
/// [`crate::CollaborativeObject`].
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Objects {
|
||||
/// If the local peer has a [`Reference`] for this particular
|
||||
/// object, then `local` should be set.
|
||||
pub local: Option<Reference>,
|
||||
/// The `remotes` are the entries for each remote peer's version
|
||||
/// of the particular object.
|
||||
pub remotes: Vec<Reference>,
|
||||
}
|
||||
pub struct Objects(Vec<Reference>);
|
||||
|
||||
impl Objects {
|
||||
pub fn new(reference: Reference) -> Self {
|
||||
Self(vec![reference])
|
||||
}
|
||||
|
||||
pub fn push(&mut self, reference: Reference) {
|
||||
self.0.push(reference)
|
||||
}
|
||||
|
||||
/// Return an iterator over the `local` and `remotes` of the given
|
||||
/// [`Objects`].
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Reference> {
|
||||
self.local.iter().chain(self.remotes.iter())
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<Reference>> for Objects {
|
||||
fn from(refs: Vec<Reference>) -> Self {
|
||||
Objects(refs)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -61,18 +68,13 @@ pub trait Storage {
|
|||
/// particular object
|
||||
fn objects(
|
||||
&self,
|
||||
identifier: &Self::Identifier,
|
||||
typename: &TypeName,
|
||||
object_id: &ObjectId,
|
||||
) -> Result<Objects, Self::ObjectsError>;
|
||||
|
||||
/// Get all references to objects of a given type within a particular
|
||||
/// identity
|
||||
fn types(
|
||||
&self,
|
||||
identifier: &Self::Identifier,
|
||||
typename: &TypeName,
|
||||
) -> Result<HashMap<ObjectId, Objects>, Self::TypesError>;
|
||||
fn types(&self, typename: &TypeName) -> Result<HashMap<ObjectId, Objects>, Self::TypesError>;
|
||||
|
||||
/// Update a ref to a particular collaborative object
|
||||
fn update(
|
||||
|
|
|
|||
|
|
@ -107,26 +107,10 @@ impl object::Storage for Storage {
|
|||
|
||||
fn objects(
|
||||
&self,
|
||||
identifier: &Self::Identifier,
|
||||
typename: &crate::TypeName,
|
||||
object_id: &ObjectId,
|
||||
) -> Result<object::Objects, Self::ObjectsError> {
|
||||
let name = format!(
|
||||
"refs/rad/{}/cobs/{}/{}",
|
||||
identifier.to_path(),
|
||||
typename,
|
||||
object_id
|
||||
);
|
||||
let glob = format!(
|
||||
"refs/rad/{}/*/cobs/{}/{}",
|
||||
identifier.name.as_str(),
|
||||
typename,
|
||||
object_id
|
||||
);
|
||||
let local = {
|
||||
let r = self.raw.find_reference(&name)?;
|
||||
Some(Reference::try_from(r)?)
|
||||
};
|
||||
let glob = format!("refs/rad/*/cobs/{}/{}", typename, object_id);
|
||||
let remotes = self
|
||||
.raw
|
||||
.references_glob(&glob)?
|
||||
|
|
@ -135,31 +119,28 @@ impl object::Storage for Storage {
|
|||
.and_then(|r| Reference::try_from(r).map_err(error::Objects::from))
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(object::Objects { local, remotes })
|
||||
Ok(remotes.into())
|
||||
}
|
||||
|
||||
fn types(
|
||||
&self,
|
||||
identifier: &Self::Identifier,
|
||||
typename: &crate::TypeName,
|
||||
) -> Result<HashMap<ObjectId, object::Objects>, Self::TypesError> {
|
||||
let mut objects = HashMap::new();
|
||||
let prefix = format!("refs/rad/{}/cobs/{}", identifier.to_path(), typename);
|
||||
for r in self.raw.references()? {
|
||||
for r in self.raw.references_glob("refs/rad/*")? {
|
||||
let r = r?;
|
||||
let name = r.name().unwrap();
|
||||
println!("NAME: {}", name);
|
||||
let oid = r
|
||||
.target()
|
||||
.map(ObjectId::from)
|
||||
.expect("BUG: the cob references should be direct");
|
||||
if name.starts_with(&prefix) {
|
||||
objects.insert(
|
||||
oid,
|
||||
object::Objects {
|
||||
local: Some(Reference::try_from(r)?),
|
||||
remotes: Vec::new(),
|
||||
},
|
||||
);
|
||||
if name.contains(typename.as_str()) {
|
||||
let reference = Reference::try_from(r)?;
|
||||
objects
|
||||
.entry(oid)
|
||||
.and_modify(|objs: &mut object::Objects| objs.push(reference.clone()))
|
||||
.or_insert_with(|| object::Objects::new(reference));
|
||||
}
|
||||
}
|
||||
Ok(objects)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ fn roundtrip() {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let expected = get(&storage, &proj.identifier(), &typename, cob.id())
|
||||
let expected = get(&storage, &typename, cob.id())
|
||||
.unwrap()
|
||||
.expect("BUG: cob was missing");
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ fn list_cobs() {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let mut expected = list(&storage, &proj.identifier(), &typename).unwrap();
|
||||
let mut expected = list(&storage, &typename).unwrap();
|
||||
expected.sort_by(|x, y| x.id().cmp(y.id()));
|
||||
|
||||
let mut actual = vec![issue_1, issue_2];
|
||||
|
|
@ -115,7 +115,7 @@ fn update_cob() {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let not_expected = get(&storage, &proj.identifier(), &typename, cob.id())
|
||||
let not_expected = get(&storage, &typename, cob.id())
|
||||
.unwrap()
|
||||
.expect("BUG: cob was missing");
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ fn update_cob() {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let expected = get(&storage, &proj.identifier(), &typename, updated.id())
|
||||
let expected = get(&storage, &typename, updated.id())
|
||||
.unwrap()
|
||||
.expect("BUG: cob was missing");
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,12 @@ use thiserror::Error;
|
|||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
||||
pub struct TypeName(String);
|
||||
|
||||
impl TypeName {
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TypeName {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(self.0.as_str())
|
||||
|
|
|
|||
Loading…
Reference in New Issue