wick_rpc/
types.rs

1/// Conversion utilities for RPC data structures.
2pub(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/// Important statistics for the hosted components.
12#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
13#[non_exhaustive]
14pub struct Statistics {
15  /// The name of the component.
16  pub name: String,
17  /// The number of times a component has been called.
18  pub runs: u32,
19  /// The number of times the component resulted in an unrecoverable error.
20  pub errors: u32,
21  /// Execution duration statistics.
22  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/// Duration related statistics.
47#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
48#[non_exhaustive]
49pub struct DurationStatistics {
50  /// The maximum duration.
51  #[serde(with = "as_micros")]
52  pub max_time: Duration,
53  /// The minimum duration.
54  #[serde(with = "as_micros")]
55  pub min_time: Duration,
56  /// The average duration.
57  #[serde(with = "as_micros")]
58  pub average_time: Duration,
59  /// The total duration.
60  #[serde(with = "as_micros")]
61  pub total_time: Duration,
62}
63
64impl DurationStatistics {
65  /// Creates a new [DurationStatistics] instance.
66  #[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  /// Converts a [RpcPacket] into a [Packet].
79  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}