Skip to main content

wfe_core/models/
execution_pointer.rs

1use std::collections::HashMap;
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use super::status::PointerStatus;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct ExecutionPointer {
10    pub id: String,
11    pub step_id: usize,
12    pub active: bool,
13    pub status: PointerStatus,
14    pub sleep_until: Option<DateTime<Utc>>,
15    pub persistence_data: Option<serde_json::Value>,
16    pub start_time: Option<DateTime<Utc>>,
17    pub end_time: Option<DateTime<Utc>>,
18    pub event_name: Option<String>,
19    pub event_key: Option<String>,
20    pub event_published: bool,
21    pub event_data: Option<serde_json::Value>,
22    pub step_name: Option<String>,
23    pub retry_count: u32,
24    pub children: Vec<String>,
25    pub context_item: Option<serde_json::Value>,
26    pub predecessor_id: Option<String>,
27    pub outcome: Option<serde_json::Value>,
28    pub scope: Vec<String>,
29    pub extension_attributes: HashMap<String, serde_json::Value>,
30}
31
32impl ExecutionPointer {
33    pub fn new(step_id: usize) -> Self {
34        Self {
35            id: uuid::Uuid::new_v4().to_string(),
36            step_id,
37            active: true,
38            status: PointerStatus::Pending,
39            sleep_until: None,
40            persistence_data: None,
41            start_time: None,
42            end_time: None,
43            event_name: None,
44            event_key: None,
45            event_published: false,
46            event_data: None,
47            step_name: None,
48            retry_count: 0,
49            children: Vec::new(),
50            context_item: None,
51            predecessor_id: None,
52            outcome: None,
53            scope: Vec::new(),
54            extension_attributes: HashMap::new(),
55        }
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62    use pretty_assertions::assert_eq;
63
64    #[test]
65    fn new_pointer_has_correct_defaults() {
66        let pointer = ExecutionPointer::new(0);
67        assert_eq!(pointer.step_id, 0);
68        assert!(pointer.active);
69        assert_eq!(pointer.status, PointerStatus::Pending);
70        assert_eq!(pointer.retry_count, 0);
71        assert!(pointer.children.is_empty());
72        assert!(pointer.scope.is_empty());
73        assert!(!pointer.event_published);
74    }
75
76    #[test]
77    fn new_pointer_generates_unique_ids() {
78        let p1 = ExecutionPointer::new(0);
79        let p2 = ExecutionPointer::new(0);
80        assert_ne!(p1.id, p2.id);
81    }
82
83    #[test]
84    fn serde_round_trip() {
85        let mut pointer = ExecutionPointer::new(3);
86        pointer.status = PointerStatus::Running;
87        pointer.retry_count = 2;
88        pointer.persistence_data = Some(serde_json::json!({"step_state": true}));
89        pointer.children = vec!["child-1".into(), "child-2".into()];
90
91        let json = serde_json::to_string(&pointer).unwrap();
92        let deserialized: ExecutionPointer = serde_json::from_str(&json).unwrap();
93
94        assert_eq!(pointer.id, deserialized.id);
95        assert_eq!(pointer.step_id, deserialized.step_id);
96        assert_eq!(pointer.status, deserialized.status);
97        assert_eq!(pointer.retry_count, deserialized.retry_count);
98        assert_eq!(pointer.persistence_data, deserialized.persistence_data);
99        assert_eq!(pointer.children, deserialized.children);
100    }
101}