Skip to main content

pragma_common/entries/
volume.rs

1#[cfg(feature = "proto")]
2use prost::Message;
3
4use crate::{InstrumentType, Pair};
5#[cfg(feature = "proto")]
6use crate::{ProtoDeserialize, ProtoSerialize};
7
8#[derive(Debug, Clone, PartialEq)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10#[cfg_attr(
11    feature = "borsh",
12    derive(borsh::BorshSerialize, borsh::BorshDeserialize)
13)]
14#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
15pub struct VolumeEntry {
16    pub source: String,
17    pub instrument_type: InstrumentType,
18    pub pair: Pair,
19    pub volume_daily: f64,
20    pub timestamp_ms: i64,
21    pub received_timestamp_ms: i64,
22}
23
24#[cfg(feature = "proto")]
25impl VolumeEntry {
26    fn to_proto(&self) -> crate::schema::VolumeEntry {
27        crate::schema::VolumeEntry {
28            source: self.source.clone(),
29            instrument_type: match self.instrument_type {
30                InstrumentType::Spot => crate::schema::InstrumentType::Spot as i32,
31                InstrumentType::Perp => crate::schema::InstrumentType::Perp as i32,
32            },
33            pair: Some(crate::schema::Pair {
34                base: self.pair.base.clone(),
35                quote: self.pair.quote.clone(),
36            }),
37            volume_daily: self.volume_daily,
38            timestamp_ms: self.timestamp_ms,
39            received_timestamp_ms: self.received_timestamp_ms,
40        }
41    }
42
43    fn from_proto(proto: crate::schema::VolumeEntry) -> Result<Self, prost::DecodeError> {
44        let pair = proto
45            .pair
46            .ok_or_else(|| prost::DecodeError::new("Missing pair field in VolumeEntry"))?;
47
48        let instrument_type = match proto.instrument_type {
49            x if x == crate::schema::InstrumentType::Spot as i32 => InstrumentType::Spot,
50            x if x == crate::schema::InstrumentType::Perp as i32 => InstrumentType::Perp,
51            _ => {
52                return Err(prost::DecodeError::new(format!(
53                    "Invalid instrument_type value: {}",
54                    proto.instrument_type,
55                )))
56            }
57        };
58
59        Ok(VolumeEntry {
60            source: proto.source,
61            instrument_type,
62            pair: Pair {
63                base: pair.base,
64                quote: pair.quote,
65            },
66            volume_daily: proto.volume_daily,
67            timestamp_ms: proto.timestamp_ms,
68            received_timestamp_ms: proto.received_timestamp_ms,
69        })
70    }
71}
72
73#[cfg(feature = "proto")]
74impl ProtoSerialize for VolumeEntry {
75    fn to_proto_bytes(&self) -> Vec<u8> {
76        let proto = self.to_proto();
77        let mut buf = Vec::new();
78        proto
79            .encode(&mut buf)
80            .expect("Failed to encode VolumeEntry to protobuf");
81        buf
82    }
83}
84
85#[cfg(feature = "proto")]
86impl ProtoDeserialize for VolumeEntry {
87    fn from_proto_bytes(bytes: &[u8]) -> Result<Self, prost::DecodeError> {
88        let proto = crate::schema::VolumeEntry::decode(bytes)?;
89        Self::from_proto(proto)
90    }
91}