1use std::collections::VecDeque;
2use std::ops::Index;
3
4use sk_core::prelude::*;
5use tracing::*;
6
7use crate::{
8 TraceAction,
9 TraceEvent,
10};
11
12#[derive(Clone, Default)]
13pub struct TraceEventList(VecDeque<TraceEvent>);
14
15impl TraceEventList {
16 pub(crate) fn append(&mut self, ts: i64, obj: &DynamicObject, action: TraceAction) {
17 info!(
18 "{:?} @ {ts}: {} {}",
19 action,
20 obj.types
21 .clone()
22 .map(|tm| format!("{}.{}", tm.api_version, tm.kind))
23 .unwrap_or("<unknown type>".into()),
24 obj.namespaced_name(),
25 );
26
27 let obj = obj.clone();
28 match self.0.back_mut() {
29 Some(evt) if evt.ts == ts => match action {
30 TraceAction::ObjectApplied => evt.applied_objs.push(obj),
31 TraceAction::ObjectDeleted => evt.deleted_objs.push(obj),
32 },
33 _ => {
34 let evt = match action {
35 TraceAction::ObjectApplied => TraceEvent { ts, applied_objs: vec![obj], ..Default::default() },
36 TraceAction::ObjectDeleted => TraceEvent { ts, deleted_objs: vec![obj], ..Default::default() },
37 };
38 self.0.push_back(evt);
39 },
40 }
41 }
42
43 pub(crate) fn back(&self) -> Option<&TraceEvent> {
44 self.0.back()
45 }
46
47 pub(crate) fn front(&self) -> Option<&TraceEvent> {
48 self.0.front()
49 }
50
51 pub(crate) fn is_empty(&self) -> bool {
52 self.0.is_empty()
53 }
54
55 pub(crate) fn len(&self) -> usize {
56 self.0.len()
57 }
58}
59
60impl Index<usize> for TraceEventList {
61 type Output = TraceEvent;
62
63 fn index(&self, i: usize) -> &Self::Output {
64 &self.0[i]
65 }
66}
67
68impl From<VecDeque<TraceEvent>> for TraceEventList {
69 fn from(v: VecDeque<TraceEvent>) -> TraceEventList {
70 TraceEventList(v)
71 }
72}
73
74impl From<Vec<TraceEvent>> for TraceEventList {
75 fn from(v: Vec<TraceEvent>) -> TraceEventList {
76 TraceEventList(v.into())
77 }
78}
79
80impl FromIterator<TraceEvent> for TraceEventList {
81 fn from_iter<T: IntoIterator<Item = TraceEvent>>(ii: T) -> Self {
82 TraceEventList(ii.into_iter().collect())
83 }
84}