Skip to main content

made_core/entities/ceremony_instance/
participant_bindings.rs

1use crate::entities::ceremony_commands::BindParticipant;
2use crate::entities::CeremonyCommand;
3
4use super::{
5    BTreeMap, CeremonyDefinition, CeremonyInstance, CeremonyParticipantBinding, DomainError,
6    OffsetDateTime, RoleId, Specialty,
7};
8
9impl CeremonyInstance {
10    /// Seat a role for this session.
11    ///
12    /// Rebinding is allowed and deliberate: a panel can become
13    /// unavailable halfway through a working session, and a ceremony
14    /// that could not be re-seated would have to be abandoned and
15    /// started again, losing everything already decided. What was
16    /// seated before stays in the journal; the instance carries who is
17    /// seated now, which is what the next step needs.
18    pub fn bind_participant(
19        &mut self,
20        definition: &CeremonyDefinition,
21        role_id: RoleId,
22        specialty: Specialty,
23        now: OffsetDateTime,
24    ) -> Result<(), DomainError> {
25        let command = CeremonyCommand::BindParticipant(BindParticipant {
26            role_id,
27            specialty,
28            now,
29        });
30        let events = self.decide(&command, definition)?;
31        self.apply_all(&events);
32        Ok(())
33    }
34
35    #[must_use]
36    pub fn participant_bindings(&self) -> &BTreeMap<RoleId, CeremonyParticipantBinding> {
37        &self.participant_bindings
38    }
39
40    /// The specialty a role's work should be put to, if this session
41    /// seated one. `None` means the definition decides, as usual.
42    #[must_use]
43    pub fn bound_specialty(&self, role_id: &RoleId) -> Option<&Specialty> {
44        self.participant_bindings
45            .get(role_id)
46            .map(CeremonyParticipantBinding::specialty)
47    }
48}