radicle_cob/object/collaboration/
create.rs1use nonempty::NonEmpty;
4
5use crate::Embed;
6use crate::Evaluate;
7use crate::Store;
8
9use super::*;
10
11pub struct Create {
13 pub contents: NonEmpty<Vec<u8>>,
15 pub type_name: TypeName,
17 pub message: String,
19 pub embeds: Vec<Embed<Oid>>,
21 pub version: Version,
23}
24
25impl Create {
26 fn template(self) -> change::Template<git_ext::Oid> {
27 change::Template {
28 type_name: self.type_name,
29 tips: Vec::new(),
30 message: self.message,
31 embeds: self.embeds,
32 contents: self.contents,
33 }
34 }
35}
36
37pub fn create<T, S, G>(
56 storage: &S,
57 signer: &G,
58 resource: Option<Oid>,
59 related: Vec<Oid>,
60 identifier: &S::Namespace,
61 args: Create,
62) -> Result<CollaborativeObject<T>, error::Create>
63where
64 T: Evaluate<S>,
65 S: Store,
66 G: signature::Signer<crate::ExtendedSignature>,
67{
68 let type_name = args.type_name.clone();
69 let version = args.version;
70 let init_change = storage
71 .store(resource, related, signer, args.template())
72 .map_err(error::Create::from)?;
73 let object_id = init_change.id().into();
74 let object = T::init(&init_change, storage).map_err(error::Create::evaluate)?;
75
76 storage
77 .update(identifier, &type_name, &object_id, &object_id)
78 .map_err(|err| error::Create::Refs { err: Box::new(err) })?;
79
80 let history = History::new_from_root(init_change);
81
82 Ok(CollaborativeObject {
83 manifest: Manifest::new(type_name, version),
84 history,
85 object,
86 id: object_id,
87 })
88}