use crate::ElementName;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RelationshipType {
Shared,
Exclusive,
Dedicated,
Linear,
Lifeline,
}
impl RelationshipType {
#[must_use]
pub const fn requires_serialization_barrier(&self) -> bool {
matches!(self, Self::Exclusive)
}
#[must_use]
pub const fn requires_dedicated_instance(&self) -> bool {
matches!(self, Self::Dedicated)
}
#[must_use]
pub const fn implies_lifecycle_coupling(&self) -> bool {
matches!(self, Self::Lifeline)
}
#[must_use]
pub const fn is_linear(&self) -> bool {
matches!(self, Self::Linear)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Dependency {
pub target: ElementName,
pub relationship: RelationshipType,
}
impl Dependency {
#[must_use]
pub const fn shared(target: ElementName) -> Self {
Self {
target,
relationship: RelationshipType::Shared,
}
}
#[must_use]
pub const fn exclusive(target: ElementName) -> Self {
Self {
target,
relationship: RelationshipType::Exclusive,
}
}
#[must_use]
pub const fn dedicated(target: ElementName) -> Self {
Self {
target,
relationship: RelationshipType::Dedicated,
}
}
#[must_use]
pub const fn linear(target: ElementName) -> Self {
Self {
target,
relationship: RelationshipType::Linear,
}
}
#[must_use]
pub const fn lifeline(target: ElementName) -> Self {
Self {
target,
relationship: RelationshipType::Lifeline,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn name(s: &str) -> ElementName {
ElementName::new(s).unwrap()
}
#[test]
fn helper_predicates_match_variant() {
assert!(RelationshipType::Exclusive.requires_serialization_barrier());
assert!(!RelationshipType::Shared.requires_serialization_barrier());
assert!(RelationshipType::Dedicated.requires_dedicated_instance());
assert!(RelationshipType::Lifeline.implies_lifecycle_coupling());
assert!(RelationshipType::Linear.is_linear());
assert!(!RelationshipType::Shared.is_linear());
}
#[test]
fn constructors_set_the_right_relationship() {
let t = name("db");
assert_eq!(Dependency::shared(t.clone()).relationship, RelationshipType::Shared);
assert_eq!(Dependency::exclusive(t.clone()).relationship, RelationshipType::Exclusive);
assert_eq!(Dependency::dedicated(t.clone()).relationship, RelationshipType::Dedicated);
assert_eq!(Dependency::linear(t.clone()).relationship, RelationshipType::Linear);
assert_eq!(Dependency::lifeline(t).relationship, RelationshipType::Lifeline);
}
#[test]
fn serde_roundtrip() {
let d = Dependency::exclusive(name("db"));
let json = serde_json::to_string(&d).unwrap();
let back: Dependency = serde_json::from_str(&json).unwrap();
assert_eq!(d, back);
}
}