radicle_cob/object/
collaboration.rs1use std::convert::Infallible;
3use std::fmt::Debug;
4
5use git_ext::Oid;
6use nonempty::NonEmpty;
7
8use crate::change::store::{Manifest, Version};
9use crate::{change, Entry, History, ObjectId, TypeName};
10
11pub mod error;
12
13mod create;
14pub use create::{create, Create};
15
16mod get;
17pub use get::get;
18
19pub mod info;
20
21mod list;
22pub use list::list;
23
24mod remove;
25pub use remove::remove;
26
27mod update;
28pub use update::{update, Update, Updated};
29
30#[derive(Debug, Clone, PartialEq, Eq)]
32pub struct CollaborativeObject<T> {
33 pub manifest: Manifest,
35 pub object: T,
37 pub history: History,
39 pub id: ObjectId,
41}
42
43impl<T> CollaborativeObject<T> {
44 pub fn object(&self) -> &T {
45 &self.object
46 }
47
48 pub fn history(&self) -> &History {
49 &self.history
50 }
51
52 pub fn id(&self) -> &ObjectId {
53 &self.id
54 }
55
56 pub fn typename(&self) -> &TypeName {
57 &self.manifest.type_name
58 }
59
60 pub fn manifest(&self) -> &Manifest {
61 &self.manifest
62 }
63}
64
65pub trait Evaluate<R>: Sized + Debug + 'static {
67 type Error: std::error::Error + Send + Sync + 'static;
68
69 fn init(entry: &Entry, store: &R) -> Result<Self, Self::Error>;
71
72 fn apply<'a, I: Iterator<Item = (&'a Oid, &'a Entry)>>(
74 &mut self,
75 entry: &Entry,
76 concurrent: I,
77 store: &R,
78 ) -> Result<(), Self::Error>;
79}
80
81impl<R> Evaluate<R> for NonEmpty<Entry> {
82 type Error = Infallible;
83
84 fn init(entry: &Entry, _store: &R) -> Result<Self, Self::Error> {
85 Ok(Self::new(entry.clone()))
86 }
87
88 fn apply<'a, I: Iterator<Item = (&'a Oid, &'a Entry)>>(
89 &mut self,
90 entry: &Entry,
91 _concurrent: I,
92 _store: &R,
93 ) -> Result<(), Self::Error> {
94 self.push(entry.clone());
95
96 Ok(())
97 }
98}
99
100pub fn parse_refstr<R>(name: &R) -> Option<(TypeName, ObjectId)>
122where
123 R: AsRef<git_ext::ref_format::RefStr>,
124{
125 use git_ext::ref_format::Qualified;
126 let name = name.as_ref();
127 let refs_cobs = match name.to_namespaced() {
128 None => Qualified::from_refstr(name)?,
129 Some(ns) => ns.strip_namespace_recursive(),
130 };
131
132 let (_refs, _cobs, typename, mut object_id) = refs_cobs.non_empty_components();
133 let object = object_id
134 .next()
135 .and_then(|oid| oid.parse::<ObjectId>().ok())?;
136 let name = typename.parse::<TypeName>().ok()?;
137 Some((name, object))
138}