made_core/value_objects/ceremony/
ceremony_lineage.rs1use serde::{Deserialize, Deserializer, Serialize};
2
3use crate::error::DomainError;
4
5use super::{CeremonyId, ChildDepth, ChildDepthBudget, ChildGroupId, ChildPosition};
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
8pub struct CeremonyLineage {
9 root_id: CeremonyId,
10 parent_id: CeremonyId,
11 group_id: ChildGroupId,
12 position: ChildPosition,
13 depth: ChildDepth,
14 remaining_depth: ChildDepthBudget,
15}
16
17impl CeremonyLineage {
18 pub fn new(
19 root_id: CeremonyId,
20 parent_id: CeremonyId,
21 group_id: ChildGroupId,
22 position: ChildPosition,
23 depth: ChildDepth,
24 remaining_depth: ChildDepthBudget,
25 ) -> Result<Self, DomainError> {
26 let lineage = Self {
27 root_id,
28 parent_id,
29 group_id,
30 position,
31 depth,
32 remaining_depth,
33 };
34 lineage.validate()?;
35 Ok(lineage)
36 }
37 #[must_use]
38 pub fn root_id(&self) -> &CeremonyId {
39 &self.root_id
40 }
41 #[must_use]
42 pub fn parent_id(&self) -> &CeremonyId {
43 &self.parent_id
44 }
45 #[must_use]
46 pub fn group_id(&self) -> &ChildGroupId {
47 &self.group_id
48 }
49 #[must_use]
50 pub const fn position(&self) -> ChildPosition {
51 self.position
52 }
53 #[must_use]
54 pub const fn depth(&self) -> ChildDepth {
55 self.depth
56 }
57 #[must_use]
58 pub const fn remaining_depth(&self) -> ChildDepthBudget {
59 self.remaining_depth
60 }
61
62 pub fn validate(&self) -> Result<(), DomainError> {
63 let root_is_parent = self.root_id == self.parent_id;
64 if (self.depth == ChildDepth::FIRST) != root_is_parent {
65 return Err(DomainError::InvalidDocument {
66 reason: "child lineage root and parent are inconsistent with depth".to_owned(),
67 });
68 }
69 if self.depth.get() + self.remaining_depth.get() > super::MaxChildDepth::SERVER_MAX.get() {
70 return Err(DomainError::InvalidDocument {
71 reason: "child lineage exceeds the server depth ceiling".to_owned(),
72 });
73 }
74 Ok(())
75 }
76}
77
78impl<'de> Deserialize<'de> for CeremonyLineage {
79 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
80 where
81 D: Deserializer<'de>,
82 {
83 #[derive(Deserialize)]
84 struct UncheckedCeremonyLineage {
85 root_id: CeremonyId,
86 parent_id: CeremonyId,
87 group_id: ChildGroupId,
88 position: ChildPosition,
89 depth: ChildDepth,
90 remaining_depth: ChildDepthBudget,
91 }
92
93 let raw = UncheckedCeremonyLineage::deserialize(deserializer)?;
94 Self::new(
95 raw.root_id,
96 raw.parent_id,
97 raw.group_id,
98 raw.position,
99 raw.depth,
100 raw.remaining_depth,
101 )
102 .map_err(serde::de::Error::custom)
103 }
104}