use serde::{Deserialize, Serialize};
use crate::types::{ExperienceId, RelationId, Timestamp};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum RelationType {
Supports,
Contradicts,
Elaborates,
Supersedes,
Implies,
RelatedTo,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum RelationDirection {
Outgoing,
Incoming,
Both,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ExperienceRelation {
pub id: RelationId,
pub source_id: ExperienceId,
pub target_id: ExperienceId,
pub relation_type: RelationType,
pub strength: f32,
pub metadata: Option<String>,
pub created_at: Timestamp,
}
pub struct NewExperienceRelation {
pub source_id: ExperienceId,
pub target_id: ExperienceId,
pub relation_type: RelationType,
pub strength: f32,
pub metadata: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_relation_type_postcard_roundtrip() {
let types = [
RelationType::Supports,
RelationType::Contradicts,
RelationType::Elaborates,
RelationType::Supersedes,
RelationType::Implies,
RelationType::RelatedTo,
];
for rt in &types {
let bytes = postcard::to_stdvec(rt).unwrap();
let restored: RelationType = postcard::from_bytes(&bytes).unwrap();
assert_eq!(*rt, restored);
}
}
#[test]
fn test_experience_relation_postcard_roundtrip() {
let relation = ExperienceRelation {
id: RelationId::new(),
source_id: ExperienceId::new(),
target_id: ExperienceId::new(),
relation_type: RelationType::Supports,
strength: 0.85,
metadata: Some(r#"{"context": "test"}"#.to_string()),
created_at: Timestamp::now(),
};
let bytes = postcard::to_stdvec(&relation).unwrap();
let restored: ExperienceRelation = postcard::from_bytes(&bytes).unwrap();
assert_eq!(relation.id, restored.id);
assert_eq!(relation.source_id, restored.source_id);
assert_eq!(relation.target_id, restored.target_id);
assert_eq!(relation.relation_type, restored.relation_type);
assert_eq!(relation.strength, restored.strength);
assert_eq!(relation.metadata, restored.metadata);
}
#[test]
fn test_relation_type_copy_and_eq() {
let a = RelationType::Contradicts;
let b = a; assert_eq!(a, b);
}
#[test]
fn test_relation_direction_variants() {
assert_ne!(RelationDirection::Outgoing, RelationDirection::Incoming);
assert_ne!(RelationDirection::Outgoing, RelationDirection::Both);
assert_ne!(RelationDirection::Incoming, RelationDirection::Both);
}
}