1pub(crate) mod conversions;
3use std::time::Duration;
4
5use serde::{Deserialize, Serialize};
6pub use wick_interface_types::*;
7use wick_packet::{Metadata, Packet, PacketError, PacketPayload, WickMetadata};
8
9use crate::rpc::{self, packet as rpc_packet, Packet as RpcPacket};
10
11#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
13#[non_exhaustive]
14pub struct Statistics {
15 pub name: String,
17 pub runs: u32,
19 pub errors: u32,
21 pub execution_duration: Option<DurationStatistics>,
23}
24
25mod as_micros {
26 use std::convert::TryInto;
27 use std::time::Duration;
28
29 use serde::{Deserialize, Deserializer, Serializer};
30
31 pub(crate) fn serialize<S>(duration: &Duration, serializer: S) -> Result<S::Ok, S::Error>
32 where
33 S: Serializer,
34 {
35 serializer.serialize_u64(duration.as_micros().try_into().unwrap_or(u64::MAX))
36 }
37 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Duration, D::Error>
38 where
39 D: Deserializer<'de>,
40 {
41 let micros = u64::deserialize(deserializer)?;
42 Ok(Duration::from_micros(micros))
43 }
44}
45
46#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
48#[non_exhaustive]
49pub struct DurationStatistics {
50 #[serde(with = "as_micros")]
52 pub max_time: Duration,
53 #[serde(with = "as_micros")]
55 pub min_time: Duration,
56 #[serde(with = "as_micros")]
58 pub average_time: Duration,
59 #[serde(with = "as_micros")]
61 pub total_time: Duration,
62}
63
64impl DurationStatistics {
65 #[must_use]
67 pub const fn new(min_time: Duration, max_time: Duration, average_time: Duration, total_time: Duration) -> Self {
68 Self {
69 max_time,
70 min_time,
71 average_time,
72 total_time,
73 }
74 }
75}
76
77impl RpcPacket {
78 pub fn into_packet(self) -> Packet {
80 self.into()
81 }
82}
83
84impl From<RpcPacket> for Packet {
85 fn from(v: RpcPacket) -> Self {
86 let (op, port, done) = v.metadata.map_or_else(
87 || (0, Packet::FATAL_ERROR.to_owned(), 0_u8),
88 |m| (m.index, m.port, m.flags.try_into().unwrap()),
89 );
90 Self::new_raw(
91 v.data
92 .map_or(PacketPayload::fatal_error("Could not decode RPC message"), |p| p.into()),
93 Metadata::new(op),
94 WickMetadata::new(port, done),
95 )
96 }
97}
98
99impl From<rpc_packet::Data> for PacketPayload {
100 fn from(v: rpc_packet::Data) -> Self {
101 match v {
102 rpc_packet::Data::Ok(v) => PacketPayload::Ok(match v.data {
103 Some(rpc::ok::Data::Messagepack(v)) => Some(v.into()),
104 Some(rpc::ok::Data::Json(_v)) => todo!(),
105 None => unreachable!(),
106 }),
107
108 rpc_packet::Data::Err(v) => PacketPayload::Err(PacketError::new(v.message)),
109 }
110 }
111}
112
113impl From<PacketPayload> for rpc_packet::Data {
114 fn from(v: PacketPayload) -> Self {
115 match v {
116 PacketPayload::Ok(v) => rpc_packet::Data::Ok(rpc::Ok {
117 data: Some(rpc::ok::Data::Messagepack(v.map_or_else(Vec::new, |v| v.to_vec()))),
118 }),
119 PacketPayload::Err(e) => rpc_packet::Data::Err(rpc::Err {
120 message: e.msg().to_owned(),
121 code: 513,
122 }),
123 }
124 }
125}