use nonempty::NonEmpty;
use crate::Embed;
use crate::Evaluate;
use super::*;
pub struct Create {
pub contents: NonEmpty<Vec<u8>>,
pub type_name: TypeName,
pub message: String,
pub embeds: Vec<Embed<Oid>>,
pub version: Version,
}
impl Create {
fn template(self) -> change::Template<oid::Oid> {
change::Template {
type_name: self.type_name,
tips: Vec::new(),
message: self.message,
embeds: self.embeds,
contents: self.contents,
}
}
}
pub fn create<T, S, G>(
storage: &S,
signer: &G,
resource: Option<Oid>,
related: Vec<Oid>,
identifier: &<S as crate::object::Storage>::Namespace,
args: Create,
) -> Result<CollaborativeObject<T>, error::Create>
where
T: Evaluate<S>,
S: crate::object::Storage
+ crate::change::Storage<
ObjectId = crate::object::Oid,
Parent = crate::object::Oid,
Signatures = crate::ExtendedSignature,
>,
G: signature::Signer<crate::ExtendedSignature>,
{
let type_name = args.type_name.clone();
let version = args.version;
let init_change = storage
.store(resource, related, signer, args.template())
.map_err(Into::<error::Create>::into)?;
let object_id = init_change.id().into();
let object = T::init(&init_change, storage).map_err(error::Create::evaluate)?;
storage
.update(identifier, &type_name, &object_id, &object_id)
.map_err(|err| error::Create::Refs { err: Box::new(err) })?;
let history = History::new_from_root(init_change);
Ok(CollaborativeObject {
manifest: Manifest::new(type_name, version),
history,
object,
id: object_id,
})
}