made_core/entities/ceremony_instance/decisions/
start.rs1use time::OffsetDateTime;
2
3use crate::entities::ceremony_events::{CeremonyInstanceStarted, MemoryRecalled};
4use crate::entities::{
5 CeremonyDefinition, CeremonyEvent, CeremonyInstance, PublishedCeremonyDefinition,
6};
7use crate::error::DomainError;
8use crate::value_objects::{
9 CeremonyContext, CeremonyDefinitionDigest, CeremonyId, SessionRecollection,
10};
11
12impl CeremonyInstance {
13 pub fn decide_start(
25 id: CeremonyId,
26 definition: &CeremonyDefinition,
27 context: CeremonyContext,
28 recollection: Option<SessionRecollection>,
29 now: OffsetDateTime,
30 ) -> Result<Vec<CeremonyEvent>, DomainError> {
31 Ok(Self::opening_batch(
32 Self::opening(id, definition, context, now, None)?,
33 recollection,
34 now,
35 ))
36 }
37
38 pub fn decide_start_bound(
41 id: CeremonyId,
42 published: &PublishedCeremonyDefinition,
43 context: CeremonyContext,
44 recollection: Option<SessionRecollection>,
45 now: OffsetDateTime,
46 ) -> Result<Vec<CeremonyEvent>, DomainError> {
47 Ok(Self::opening_batch(
48 Self::opening(
49 id,
50 published.definition(),
51 context,
52 now,
53 Some(published.digest()),
54 )?,
55 recollection,
56 now,
57 ))
58 }
59
60 fn opening_batch(
69 opening: CeremonyInstanceStarted,
70 recollection: Option<SessionRecollection>,
71 now: OffsetDateTime,
72 ) -> Vec<CeremonyEvent> {
73 let mut events = vec![CeremonyEvent::CeremonyInstanceStarted(opening)];
74 if let Some(recollection) = recollection.filter(|recalled| !recalled.is_empty()) {
75 events.push(CeremonyEvent::MemoryRecalled(MemoryRecalled {
76 recollection,
77 recalled_at: now,
78 }));
79 }
80 events
81 }
82
83 pub(in crate::entities::ceremony_instance) fn opening(
86 id: CeremonyId,
87 definition: &CeremonyDefinition,
88 context: CeremonyContext,
89 now: OffsetDateTime,
90 bound_definition: Option<CeremonyDefinitionDigest>,
91 ) -> Result<CeremonyInstanceStarted, DomainError> {
92 let missing = definition
93 .inputs()
94 .values()
95 .filter(|input| input.requirement().is_required())
96 .filter(|input| context.attributes().get(input.name().as_str()).is_none())
97 .map(|input| input.name().as_str())
98 .collect::<Vec<_>>();
99 if !missing.is_empty() {
100 return Err(DomainError::InvalidDocument {
101 reason: format!("missing required ceremony inputs: {}", missing.join(", ")),
102 });
103 }
104 Ok(CeremonyInstanceStarted {
105 ceremony_id: id,
106 definition_name: definition.name().clone(),
107 definition_version: definition.version().clone(),
108 initial_state: definition.initial_state_id().clone(),
109 step_ids: definition.steps().keys().cloned().collect(),
110 context,
111 bound_definition,
112 created_at: now,
113 })
114 }
115}