1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4use super::entity::{EntityId, Value};
5use super::narrative_fn::NarrativeFunction;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub enum Mood {
10 Neutral,
11 Tense,
12 Warm,
13 Dread,
14 Euphoric,
15 Somber,
16 Chaotic,
17 Intimate,
18}
19
20impl Mood {
21 pub fn tag(&self) -> &'static str {
23 match self {
24 Self::Neutral => "mood:neutral",
25 Self::Tense => "mood:tense",
26 Self::Warm => "mood:warm",
27 Self::Dread => "mood:dread",
28 Self::Euphoric => "mood:euphoric",
29 Self::Somber => "mood:somber",
30 Self::Chaotic => "mood:chaotic",
31 Self::Intimate => "mood:intimate",
32 }
33 }
34}
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
38pub enum Stakes {
39 Trivial,
40 Low,
41 Medium,
42 High,
43 Critical,
44}
45
46impl Stakes {
47 pub fn tag(&self) -> &'static str {
49 match self {
50 Self::Trivial => "stakes:trivial",
51 Self::Low => "stakes:low",
52 Self::Medium => "stakes:medium",
53 Self::High => "stakes:high",
54 Self::Critical => "stakes:critical",
55 }
56 }
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
61pub enum Outcome {
62 Success,
63 Failure,
64 Partial,
65 Ambiguous,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct EntityRef {
71 pub entity_id: EntityId,
72 pub role: String,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct Event {
79 pub event_type: String,
80 pub participants: Vec<EntityRef>,
81 pub location: Option<EntityRef>,
82 pub mood: Mood,
83 pub stakes: Stakes,
84 pub outcome: Option<Outcome>,
85 pub narrative_fn: NarrativeFunction,
86 pub metadata: HashMap<String, Value>,
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn event_creation() {
95 let event = Event {
96 event_type: "accusation".to_string(),
97 participants: vec![
98 EntityRef {
99 entity_id: EntityId(1),
100 role: "subject".to_string(),
101 },
102 EntityRef {
103 entity_id: EntityId(2),
104 role: "target".to_string(),
105 },
106 ],
107 location: Some(EntityRef {
108 entity_id: EntityId(100),
109 role: "location".to_string(),
110 }),
111 mood: Mood::Tense,
112 stakes: Stakes::High,
113 outcome: None,
114 narrative_fn: NarrativeFunction::Confrontation,
115 metadata: HashMap::from([(
116 "held_item".to_string(),
117 Value::String("wine glass".to_string()),
118 )]),
119 };
120 assert_eq!(event.mood, Mood::Tense);
121 assert_eq!(event.stakes, Stakes::High);
122 assert_eq!(event.participants.len(), 2);
123 assert_eq!(event.participants[0].role, "subject");
124 assert!(event.location.is_some());
125 }
126
127 #[test]
128 fn mood_tags() {
129 assert_eq!(Mood::Tense.tag(), "mood:tense");
130 assert_eq!(Mood::Neutral.tag(), "mood:neutral");
131 assert_eq!(Mood::Dread.tag(), "mood:dread");
132 assert_eq!(Mood::Intimate.tag(), "mood:intimate");
133 }
134
135 #[test]
136 fn stakes_tags() {
137 assert_eq!(Stakes::Trivial.tag(), "stakes:trivial");
138 assert_eq!(Stakes::Critical.tag(), "stakes:critical");
139 assert_eq!(Stakes::High.tag(), "stakes:high");
140 }
141
142 #[test]
143 fn outcome_variants() {
144 assert_eq!(Outcome::Success, Outcome::Success);
145 assert_ne!(Outcome::Success, Outcome::Failure);
146 }
147
148 #[test]
149 fn entity_ref_roles() {
150 let witness = EntityRef {
151 entity_id: EntityId(3),
152 role: "witness".to_string(),
153 };
154 assert_eq!(witness.role, "witness");
155 }
156}