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