This repository has no description
1use knot_cob::{ChangePayload, Checkpoint, CobError, CobHome, CobStore, Evaluate};
2use knot_cobs::{GrantChange, Roster};
3use knot_runtime::Signer;
4use knot_types::UnixSeconds;
5
6use crate::error::XrpcError;
7
8pub(crate) fn grant_set_apply<E>(
9 store: &CobStore,
10 home: &CobHome,
11 change: E::Change,
12 signer: &dyn Signer,
13 now: UnixSeconds,
14 create_if_absent: bool,
15) -> Result<bool, XrpcError>
16where
17 E: Checkpoint + Evaluate<State = Roster>,
18 E::Change: ChangePayload + Clone + GrantChange,
19{
20 match store.list::<E>().map_err(XrpcError::from)?.as_slice() {
21 [] if create_if_absent => {
22 store
23 .create(home, &change, signer, now)
24 .map_err(XrpcError::from)?;
25 Ok(true)
26 }
27 [] => Ok(false),
28 [object] => store
29 .update_maybe_checkpointed::<E, CobError>(home, *object, signer, now, |roster| {
30 let redundant = change.adds() == roster.contains(change.subject());
31 Ok(if redundant {
32 None
33 } else {
34 Some(change.clone())
35 })
36 })
37 .map(|change_id| change_id.is_some())
38 .map_err(XrpcError::from),
39 many => Err(XrpcError::internal(format!(
40 "{} collaborative objects of one type share namespace",
41 many.len()
42 ))),
43 }
44}