#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum RelationshipStage {
#[default]
Stranger,
Acquaintance,
Established,
Intimate,
Estranged,
}
impl RelationshipStage {
#[must_use]
pub const fn propensity_weight(&self) -> f32 {
match self {
RelationshipStage::Stranger => 0.6,
RelationshipStage::Acquaintance => 0.4,
RelationshipStage::Established => 0.2,
RelationshipStage::Intimate => 0.1,
RelationshipStage::Estranged => 0.3,
}
}
#[must_use]
pub const fn trustworthiness_weight(&self) -> f32 {
match self {
RelationshipStage::Stranger => 0.4,
RelationshipStage::Acquaintance => 0.6,
RelationshipStage::Established => 0.8,
RelationshipStage::Intimate => 0.9,
RelationshipStage::Estranged => 0.7,
}
}
#[must_use]
pub const fn risk_modifier(&self) -> f32 {
match self {
RelationshipStage::Stranger => 0.3,
RelationshipStage::Acquaintance => 0.2,
RelationshipStage::Established => 0.0,
RelationshipStage::Intimate => -0.1,
RelationshipStage::Estranged => 0.4,
}
}
#[must_use]
pub const fn name(&self) -> &'static str {
match self {
RelationshipStage::Stranger => "Stranger",
RelationshipStage::Acquaintance => "Acquaintance",
RelationshipStage::Established => "Established",
RelationshipStage::Intimate => "Intimate",
RelationshipStage::Estranged => "Estranged",
}
}
#[must_use]
pub const fn description(&self) -> &'static str {
match self {
RelationshipStage::Stranger => "No significant interaction history",
RelationshipStage::Acquaintance => "Limited interactions, forming impressions",
RelationshipStage::Established => "Regular relationship with consistent patterns",
RelationshipStage::Intimate => "Deep trust and extensive history",
RelationshipStage::Estranged => "Previously close but now deteriorated",
}
}
#[must_use]
pub const fn all() -> [RelationshipStage; 5] {
[
RelationshipStage::Stranger,
RelationshipStage::Acquaintance,
RelationshipStage::Established,
RelationshipStage::Intimate,
RelationshipStage::Estranged,
]
}
#[must_use]
pub const fn is_positive(&self) -> bool {
matches!(
self,
RelationshipStage::Acquaintance
| RelationshipStage::Established
| RelationshipStage::Intimate
)
}
#[must_use]
pub const fn is_developed(&self) -> bool {
matches!(
self,
RelationshipStage::Established | RelationshipStage::Intimate
)
}
}
impl std::fmt::Display for RelationshipStage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.name())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn propensity_weight_values() {
assert!((RelationshipStage::Stranger.propensity_weight() - 0.6).abs() < f32::EPSILON);
assert!((RelationshipStage::Acquaintance.propensity_weight() - 0.4).abs() < f32::EPSILON);
assert!((RelationshipStage::Established.propensity_weight() - 0.2).abs() < f32::EPSILON);
assert!((RelationshipStage::Intimate.propensity_weight() - 0.1).abs() < f32::EPSILON);
assert!((RelationshipStage::Estranged.propensity_weight() - 0.3).abs() < f32::EPSILON);
}
#[test]
fn trustworthiness_weight_values() {
assert!((RelationshipStage::Stranger.trustworthiness_weight() - 0.4).abs() < f32::EPSILON);
assert!(
(RelationshipStage::Acquaintance.trustworthiness_weight() - 0.6).abs() < f32::EPSILON
);
assert!(
(RelationshipStage::Established.trustworthiness_weight() - 0.8).abs() < f32::EPSILON
);
assert!((RelationshipStage::Intimate.trustworthiness_weight() - 0.9).abs() < f32::EPSILON);
assert!((RelationshipStage::Estranged.trustworthiness_weight() - 0.7).abs() < f32::EPSILON);
}
#[test]
fn weights_sum_to_one() {
for stage in RelationshipStage::all() {
let sum = stage.propensity_weight() + stage.trustworthiness_weight();
let message = format!("Stage {:?} weights sum to {}, not 1.0", stage, sum);
assert!((sum - 1.0).abs() < f32::EPSILON, "{}", message);
}
}
#[test]
fn risk_modifier_values() {
assert!((RelationshipStage::Stranger.risk_modifier() - 0.3).abs() < f32::EPSILON);
assert!((RelationshipStage::Acquaintance.risk_modifier() - 0.2).abs() < f32::EPSILON);
assert!(RelationshipStage::Established.risk_modifier().abs() < f32::EPSILON);
assert!((RelationshipStage::Intimate.risk_modifier() - (-0.1)).abs() < f32::EPSILON);
assert!((RelationshipStage::Estranged.risk_modifier() - 0.4).abs() < f32::EPSILON);
}
#[test]
fn propensity_weight_diminishes_with_stage() {
assert!(
RelationshipStage::Stranger.propensity_weight()
> RelationshipStage::Acquaintance.propensity_weight()
);
assert!(
RelationshipStage::Acquaintance.propensity_weight()
> RelationshipStage::Established.propensity_weight()
);
assert!(
RelationshipStage::Established.propensity_weight()
> RelationshipStage::Intimate.propensity_weight()
);
}
#[test]
fn name_values() {
assert_eq!(RelationshipStage::Stranger.name(), "Stranger");
assert_eq!(RelationshipStage::Acquaintance.name(), "Acquaintance");
assert_eq!(RelationshipStage::Established.name(), "Established");
assert_eq!(RelationshipStage::Intimate.name(), "Intimate");
assert_eq!(RelationshipStage::Estranged.name(), "Estranged");
}
#[test]
fn descriptions_not_empty() {
for stage in RelationshipStage::all() {
assert!(!stage.description().is_empty());
}
}
#[test]
fn all_stages() {
let all = RelationshipStage::all();
assert_eq!(all.len(), 5);
}
#[test]
fn is_positive() {
assert!(!RelationshipStage::Stranger.is_positive());
assert!(RelationshipStage::Acquaintance.is_positive());
assert!(RelationshipStage::Established.is_positive());
assert!(RelationshipStage::Intimate.is_positive());
assert!(!RelationshipStage::Estranged.is_positive());
}
#[test]
fn is_developed() {
assert!(!RelationshipStage::Stranger.is_developed());
assert!(!RelationshipStage::Acquaintance.is_developed());
assert!(RelationshipStage::Established.is_developed());
assert!(RelationshipStage::Intimate.is_developed());
assert!(!RelationshipStage::Estranged.is_developed());
}
#[test]
fn default_is_stranger() {
assert_eq!(RelationshipStage::default(), RelationshipStage::Stranger);
}
#[test]
fn display_format() {
assert_eq!(format!("{}", RelationshipStage::Intimate), "Intimate");
}
#[test]
fn equality() {
assert_eq!(RelationshipStage::Stranger, RelationshipStage::Stranger);
assert_ne!(RelationshipStage::Stranger, RelationshipStage::Intimate);
}
#[test]
fn clone_copy() {
let s1 = RelationshipStage::Established;
let s2 = s1;
let s3 = s1.clone();
assert_eq!(s1, s2);
assert_eq!(s1, s3);
}
#[test]
fn hash() {
use std::collections::HashSet;
let mut set = HashSet::new();
set.insert(RelationshipStage::Stranger);
set.insert(RelationshipStage::Stranger);
assert_eq!(set.len(), 1);
set.insert(RelationshipStage::Intimate);
assert_eq!(set.len(), 2);
}
#[test]
fn debug_format() {
let debug = format!("{:?}", RelationshipStage::Acquaintance);
assert!(debug.contains("Acquaintance"));
}
}