paramodel_elements/
dependency.rs1use crate::ElementName;
13use serde::{Deserialize, Serialize};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
17#[serde(rename_all = "snake_case")]
18pub enum RelationshipType {
19 Shared,
21 Exclusive,
24 Dedicated,
27 Linear,
30 Lifeline,
33}
34
35impl RelationshipType {
36 #[must_use]
39 pub const fn requires_serialization_barrier(&self) -> bool {
40 matches!(self, Self::Exclusive)
41 }
42
43 #[must_use]
46 pub const fn requires_dedicated_instance(&self) -> bool {
47 matches!(self, Self::Dedicated)
48 }
49
50 #[must_use]
53 pub const fn implies_lifecycle_coupling(&self) -> bool {
54 matches!(self, Self::Lifeline)
55 }
56
57 #[must_use]
59 pub const fn is_linear(&self) -> bool {
60 matches!(self, Self::Linear)
61 }
62}
63
64#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
66pub struct Dependency {
67 pub target: ElementName,
69 pub relationship: RelationshipType,
71}
72
73impl Dependency {
74 #[must_use]
76 pub const fn shared(target: ElementName) -> Self {
77 Self {
78 target,
79 relationship: RelationshipType::Shared,
80 }
81 }
82
83 #[must_use]
85 pub const fn exclusive(target: ElementName) -> Self {
86 Self {
87 target,
88 relationship: RelationshipType::Exclusive,
89 }
90 }
91
92 #[must_use]
94 pub const fn dedicated(target: ElementName) -> Self {
95 Self {
96 target,
97 relationship: RelationshipType::Dedicated,
98 }
99 }
100
101 #[must_use]
103 pub const fn linear(target: ElementName) -> Self {
104 Self {
105 target,
106 relationship: RelationshipType::Linear,
107 }
108 }
109
110 #[must_use]
112 pub const fn lifeline(target: ElementName) -> Self {
113 Self {
114 target,
115 relationship: RelationshipType::Lifeline,
116 }
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 fn name(s: &str) -> ElementName {
125 ElementName::new(s).unwrap()
126 }
127
128 #[test]
129 fn helper_predicates_match_variant() {
130 assert!(RelationshipType::Exclusive.requires_serialization_barrier());
131 assert!(!RelationshipType::Shared.requires_serialization_barrier());
132 assert!(RelationshipType::Dedicated.requires_dedicated_instance());
133 assert!(RelationshipType::Lifeline.implies_lifecycle_coupling());
134 assert!(RelationshipType::Linear.is_linear());
135 assert!(!RelationshipType::Shared.is_linear());
136 }
137
138 #[test]
139 fn constructors_set_the_right_relationship() {
140 let t = name("db");
141 assert_eq!(Dependency::shared(t.clone()).relationship, RelationshipType::Shared);
142 assert_eq!(Dependency::exclusive(t.clone()).relationship, RelationshipType::Exclusive);
143 assert_eq!(Dependency::dedicated(t.clone()).relationship, RelationshipType::Dedicated);
144 assert_eq!(Dependency::linear(t.clone()).relationship, RelationshipType::Linear);
145 assert_eq!(Dependency::lifeline(t).relationship, RelationshipType::Lifeline);
146 }
147
148 #[test]
149 fn serde_roundtrip() {
150 let d = Dependency::exclusive(name("db"));
151 let json = serde_json::to_string(&d).unwrap();
152 let back: Dependency = serde_json::from_str(&json).unwrap();
153 assert_eq!(d, back);
154 }
155}