1use super::Identifier;
2use crate::RawValue;
3use chrono::{DateTime, Utc};
4use melodium_engine::{
5 build::{
6 ContextualEnvironment as EngineContextualEnvironment, HostTreatment as EngineHostTreatment,
7 },
8 debug::{
9 DataContent as EngineDataContent, Event as EngineEvent, EventKind as EngineEventKind,
10 InfoTrack as EngineInfoTrack, TrackCreation as EngineTrackCreation,
11 TrackResult as EngineTrackResult, TransmissionDetails as EngineTransmissionDetails,
12 },
13};
14use serde::{Deserialize, Serialize};
15use std::collections::BTreeMap;
16use uuid::Uuid;
17
18#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
19#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
20#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
21pub struct Event {
22 pub timestamp: DateTime<Utc>,
23 pub kind: EventKind,
24}
25
26impl From<&EngineEvent> for Event {
27 fn from(event: &EngineEvent) -> Self {
28 Self {
29 timestamp: event.timestamp,
30 kind: (&event.kind).into(),
31 }
32 }
33}
34
35#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
36#[serde(rename_all = "snake_case")]
37#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
38#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
39pub enum EventKind {
40 ModelBuilt {
41 model: Identifier,
42 parameters: BTreeMap<String, RawValue>,
43 host_treatment: HostTreatment,
44 host_build: Option<u64>,
45 label: String,
46 },
47 ModelAdded {
48 model_id: u64,
49 model: Identifier,
50 },
51 ContinuousModelsStarted,
52 ContinuousModelsFinished,
53 TreatmentBuilt {
54 treatment: Identifier,
55 environment: ContextualEnvironment,
56 host_treatment: HostTreatment,
57 host_build: Option<u64>,
58 build_id: u64,
59 label: String,
60 },
61 TrackAdded {
62 info: InfoTrack,
63 creation: TrackCreation,
64 },
65 TrackFinished {
66 info: InfoTrack,
67 },
68 TreatmentStarted {
69 treatment: Identifier,
70 host_treatment: HostTreatment,
71 host_build: Option<u64>,
72 build_id: u64,
73 track_id: u64,
74 label: String,
75 },
76 TreatmentFinished {
77 treatment: Identifier,
78 host_treatment: HostTreatment,
79 host_build: Option<u64>,
80 build_id: u64,
81 track_id: u64,
82 label: String,
83 },
84 DataSent {
85 output: TransmissionDetails,
86 track_id: u64,
87 data: DataContent,
88 },
89 DataTransmitted {
90 output: TransmissionDetails,
91 input: TransmissionDetails,
92 track_id: u64,
93 data: DataContent,
94 },
95 DataReceived {
96 input: TransmissionDetails,
97 track_id: u64,
98 data: DataContent,
99 },
100 OutputClosed {
101 output: TransmissionDetails,
102 track_id: u64,
103 },
104 InputClosed {
105 input: TransmissionDetails,
106 track_id: u64,
107 },
108 Distant {
109 run_id: Uuid,
110 text: String,
111 },
113}
114
115impl From<&EngineEventKind> for EventKind {
116 fn from(event_kind: &EngineEventKind) -> Self {
117 match event_kind {
118 EngineEventKind::ModelBuilt {
119 model,
120 parameters,
121 host_treatment,
122 host_build,
123 label,
124 } => EventKind::ModelBuilt {
125 model: model.identifier().into(),
126 parameters: parameters
127 .iter()
128 .map(|(name, value)| (name.clone(), value.into()))
129 .collect(),
130 host_treatment: host_treatment.into(),
131 host_build: host_build.map(|id| id as u64),
132 label: label.clone(),
133 },
134 EngineEventKind::ModelAdded { model_id, model } => EventKind::ModelAdded {
135 model_id: *model_id as u64,
136 model: model.identifier().into(),
137 },
138 EngineEventKind::ContinuousModelsStarted => EventKind::ContinuousModelsStarted,
139 EngineEventKind::ContinuousModelsFinished => EventKind::ContinuousModelsFinished,
140 EngineEventKind::TreatmentBuilt {
141 treatment,
142 environment,
143 host_treatment,
144 host_build,
145 build_id,
146 label,
147 } => EventKind::TreatmentBuilt {
148 treatment: treatment.identifier().into(),
149 environment: environment.into(),
150 host_treatment: host_treatment.into(),
151 host_build: host_build.map(|id| id as u64),
152 build_id: *build_id as u64,
153 label: label.clone(),
154 },
155 EngineEventKind::TrackAdded { info, creation } => EventKind::TrackAdded {
156 info: info.into(),
157 creation: creation.into(),
158 },
159 EngineEventKind::TrackFinished { info } => {
160 EventKind::TrackFinished { info: info.into() }
161 }
162 EngineEventKind::TreatmentStarted {
163 treatment,
164 host_treatment,
165 host_build,
166 build_id,
167 track_id,
168 label,
169 } => EventKind::TreatmentStarted {
170 treatment: treatment.identifier().into(),
171 host_treatment: host_treatment.into(),
172 host_build: host_build.map(|id| id as u64),
173 build_id: *build_id as u64,
174 track_id: *track_id as u64,
175 label: label.clone(),
176 },
177 EngineEventKind::TreatmentFinished {
178 treatment,
179 host_treatment,
180 host_build,
181 build_id,
182 track_id,
183 label,
184 } => EventKind::TreatmentFinished {
185 treatment: treatment.identifier().into(),
186 host_treatment: host_treatment.into(),
187 host_build: host_build.map(|id| id as u64),
188 build_id: *build_id as u64,
189 track_id: *track_id as u64,
190 label: label.clone(),
191 },
192 EngineEventKind::DataSent {
193 output,
194 track_id,
195 data,
196 } => EventKind::DataSent {
197 output: output.into(),
198 track_id: *track_id as u64,
199 data: data.into(),
200 },
201 EngineEventKind::DataTransmitted {
202 output,
203 input,
204 track_id,
205 data,
206 } => EventKind::DataTransmitted {
207 output: output.into(),
208 input: input.into(),
209 track_id: *track_id as u64,
210 data: data.into(),
211 },
212 EngineEventKind::DataReceived {
213 input,
214 track_id,
215 data,
216 } => EventKind::DataReceived {
217 input: input.into(),
218 track_id: *track_id as u64,
219 data: data.into(),
220 },
221 EngineEventKind::OutputClosed { output, track_id } => EventKind::OutputClosed {
222 output: output.into(),
223 track_id: *track_id as u64,
224 },
225 EngineEventKind::InputClosed { input, track_id } => EventKind::InputClosed {
226 input: input.into(),
227 track_id: *track_id as u64,
228 },
229 EngineEventKind::Distant { run_id, text } => EventKind::Distant {
230 run_id: *run_id,
231 text: text.clone(),
232 },
233 }
234 }
235}
236
237#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
238#[serde(rename_all = "snake_case")]
239#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
240#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
241pub enum HostTreatment {
242 Treatment(Identifier),
243 Direct,
244}
245
246impl From<&EngineHostTreatment> for HostTreatment {
247 fn from(host_treatment: &EngineHostTreatment) -> Self {
248 match host_treatment {
249 EngineHostTreatment::Treatment(treatment) => {
250 HostTreatment::Treatment(treatment.identifier().into())
251 }
252 EngineHostTreatment::Direct => HostTreatment::Direct,
253 }
254 }
255}
256
257#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
258#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
259#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
260pub struct InfoTrack {
261 pub id: u64,
262 pub parent_id: Option<u64>,
263 pub ancestry_level: u64,
264 pub results: Option<TrackResult>,
265}
266
267impl From<&EngineInfoTrack> for InfoTrack {
268 fn from(info_track: &EngineInfoTrack) -> Self {
269 Self {
270 id: info_track.id as u64,
271 parent_id: info_track.parent_id.map(|id| id as u64),
272 ancestry_level: info_track.ancestry_level,
273 results: info_track.results.as_ref().map(TrackResult::from),
274 }
275 }
276}
277
278#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
279#[serde(rename_all = "snake_case")]
280#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
281#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
282pub enum TrackResult {
283 AllOk,
284 NotAllOk,
285}
286
287impl From<&EngineTrackResult> for TrackResult {
288 fn from(track_result: &EngineTrackResult) -> Self {
289 match track_result {
290 EngineTrackResult::AllOk(_) => TrackResult::AllOk,
291 EngineTrackResult::NotAllOk(_, _) => TrackResult::NotAllOk,
292 }
293 }
294}
295
296#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
297#[serde(rename_all = "snake_case")]
298#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
299#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
300
301pub enum TrackCreation {
302 Direct,
303 Source {
304 source: String,
305 model_id: u64,
306 parameters: BTreeMap<String, RawValue>,
307 contexts: Vec<Identifier>,
308 },
309}
310
311impl From<&EngineTrackCreation> for TrackCreation {
312 fn from(track_creation: &EngineTrackCreation) -> Self {
313 match track_creation {
314 EngineTrackCreation::Direct => TrackCreation::Direct,
315 EngineTrackCreation::Source {
316 source,
317 model_id,
318 parameters,
319 contexts,
320 } => TrackCreation::Source {
321 source: source.clone(),
322 model_id: *model_id as u64,
323 parameters: parameters
324 .iter()
325 .map(|(name, value)| (name.clone(), value.into()))
326 .collect(),
327 contexts: contexts
328 .iter()
329 .map(|context| context.descriptor().identifier().into())
330 .collect(),
331 },
332 }
333 }
334}
335
336#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
337#[serde(rename_all = "snake_case")]
338#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
339#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
340pub enum DataContent {
341 Undetailed,
342 Count { count: u64 },
343 Values { values: Vec<RawValue> },
344}
345
346impl From<&EngineDataContent> for DataContent {
347 fn from(data_content: &EngineDataContent) -> Self {
348 match data_content {
349 EngineDataContent::Undetailed => DataContent::Undetailed,
350 EngineDataContent::Count { count } => DataContent::Count {
351 count: *count as u64,
352 },
353 EngineDataContent::Values { values } => DataContent::Values {
354 values: values.iter().map(|value| value.into()).collect(),
355 },
356 }
357 }
358}
359
360#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
361#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
362#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
363pub struct ContextualEnvironment {
364 track_id: u64,
365 contexts: BTreeMap<String, Identifier>,
366 variables: BTreeMap<String, RawValue>,
367}
368
369impl From<&EngineContextualEnvironment> for ContextualEnvironment {
370 fn from(contextual_environment: &EngineContextualEnvironment) -> Self {
371 Self {
372 track_id: contextual_environment.track_id() as u64,
373 contexts: contextual_environment
374 .contexts()
375 .iter()
376 .map(|(name, context)| (name.clone(), context.descriptor().identifier().into()))
377 .collect(),
378 variables: contextual_environment
379 .variables()
380 .iter()
381 .map(|(name, value)| (name.clone(), value.into()))
382 .collect(),
383 }
384 }
385}
386
387#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
388#[cfg_attr(feature = "webassembly", derive(tsify::Tsify))]
389#[cfg_attr(feature = "webassembly", tsify(into_wasm_abi, from_wasm_abi))]
390
391pub struct TransmissionDetails {
392 pub treatment: Identifier,
393 pub host_treatment: HostTreatment,
394 pub host_build: Option<u64>,
395 pub build_id: u64,
396 pub label: String,
397 pub name: String,
398}
399
400impl From<&EngineTransmissionDetails> for TransmissionDetails {
401 fn from(details: &EngineTransmissionDetails) -> Self {
402 Self {
403 treatment: details.treatment.identifier().into(),
404 host_treatment: (&details.host_treatment).into(),
405 host_build: details.host_build.map(|id| id as u64),
406 build_id: details.build_id as u64,
407 label: details.label.clone(),
408 name: details.name.clone(),
409 }
410 }
411}