1use chrono::{DateTime, Utc};
2use uuid::Uuid;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
6#[non_exhaustive]
7pub enum EventKind {
8 Progress,
10 Partial,
12 Log,
14 Result,
16 Error,
18}
19
20#[derive(Debug, Clone)]
22pub struct Progress {
23 pub current: u64,
25 pub total: Option<u64>,
27 pub percent: Option<f32>,
29 pub message: Option<String>,
31}
32
33impl Progress {
34 pub fn new(current: u64, total: Option<u64>) -> Self {
36 let percent = total.map(|t| {
37 if t == 0 {
38 100.0
39 } else {
40 (current as f32 / t as f32) * 100.0
41 }
42 });
43 Self {
44 current,
45 total,
46 percent,
47 message: None,
48 }
49 }
50
51 #[must_use]
53 pub fn with_message(mut self, msg: impl Into<String>) -> Self {
54 self.message = Some(msg.into());
55 self
56 }
57}
58
59#[derive(Debug, Clone)]
61pub struct Event<O: Clone> {
62 pub kind: EventKind,
64 pub task_id: Uuid,
66 pub worker_id: String,
68 pub progress: Option<Progress>,
70 pub data: Option<O>,
72 pub error: Option<String>,
74 pub timestamp: DateTime<Utc>,
76}
77
78impl<O: Clone> Event<O> {
79 pub fn progress(task_id: Uuid, worker_id: impl Into<String>, p: Progress) -> Self {
81 Self {
82 kind: EventKind::Progress,
83 task_id,
84 worker_id: worker_id.into(),
85 progress: Some(p),
86 data: None,
87 error: None,
88 timestamp: Utc::now(),
89 }
90 }
91
92 pub fn partial(task_id: Uuid, worker_id: impl Into<String>, data: O) -> Self {
94 Self {
95 kind: EventKind::Partial,
96 task_id,
97 worker_id: worker_id.into(),
98 progress: None,
99 data: Some(data),
100 error: None,
101 timestamp: Utc::now(),
102 }
103 }
104
105 pub fn log(task_id: Uuid, worker_id: impl Into<String>, message: impl Into<String>) -> Self {
107 Self {
108 kind: EventKind::Log,
109 task_id,
110 worker_id: worker_id.into(),
111 progress: None,
112 data: None,
113 error: Some(message.into()),
114 timestamp: Utc::now(),
115 }
116 }
117
118 pub fn result(task_id: Uuid, worker_id: impl Into<String>, data: O) -> Self {
120 Self {
121 kind: EventKind::Result,
122 task_id,
123 worker_id: worker_id.into(),
124 progress: None,
125 data: Some(data),
126 error: None,
127 timestamp: Utc::now(),
128 }
129 }
130
131 pub fn error(task_id: Uuid, worker_id: impl Into<String>, err: impl Into<String>) -> Self {
133 Self {
134 kind: EventKind::Error,
135 task_id,
136 worker_id: worker_id.into(),
137 progress: None,
138 data: None,
139 error: Some(err.into()),
140 timestamp: Utc::now(),
141 }
142 }
143}