use {
crate::{price::Price, rate::Rate, time::TimestampUs, PriceFeedId},
derive_more::From,
serde::{Deserialize, Serialize},
};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PriceFeedDataV2 {
pub price_feed_id: PriceFeedId,
pub source_timestamp_us: TimestampUs,
pub publisher_timestamp_us: TimestampUs,
pub price: Option<Price>,
pub best_bid_price: Option<Price>,
pub best_ask_price: Option<Price>,
pub funding_rate: Option<Rate>,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PriceFeedDataV1 {
pub price_feed_id: PriceFeedId,
pub source_timestamp_us: TimestampUs,
pub publisher_timestamp_us: TimestampUs,
#[serde(with = "crate::serde_price_as_i64")]
pub price: Option<Price>,
#[serde(with = "crate::serde_price_as_i64")]
pub best_bid_price: Option<Price>,
#[serde(with = "crate::serde_price_as_i64")]
pub best_ask_price: Option<Price>,
}
impl From<PriceFeedDataV1> for PriceFeedDataV2 {
fn from(v0: PriceFeedDataV1) -> Self {
Self {
price_feed_id: v0.price_feed_id,
source_timestamp_us: v0.source_timestamp_us,
publisher_timestamp_us: v0.publisher_timestamp_us,
price: v0.price,
best_bid_price: v0.best_bid_price,
best_ask_price: v0.best_ask_price,
funding_rate: None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, From)]
#[serde(tag = "type")]
#[serde(rename_all = "camelCase")]
pub enum ServerResponse {
UpdateDeserializationError(UpdateDeserializationErrorResponse),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UpdateDeserializationErrorResponse {
pub error: String,
}
#[test]
fn price_feed_data_v1_serde() {
let data = [
1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 2, 0, 0, 0, 0, 0, 0, ];
let expected = PriceFeedDataV1 {
price_feed_id: PriceFeedId(1),
source_timestamp_us: TimestampUs::from_micros(2),
publisher_timestamp_us: TimestampUs::from_micros(3),
price: Some(Price::from_nonzero_mantissa(4.try_into().unwrap())),
best_bid_price: Some(Price::from_nonzero_mantissa(5.try_into().unwrap())),
best_ask_price: Some(Price::from_nonzero_mantissa(
(2 * 256 + 6).try_into().unwrap(),
)),
};
assert_eq!(
bincode::serde::decode_from_slice::<PriceFeedDataV1, _>(&data, bincode::config::legacy())
.unwrap()
.0,
expected
);
assert_eq!(
bincode::serde::encode_to_vec(&expected, bincode::config::legacy()).unwrap(),
data
);
let data2 = [
1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ];
let expected2 = PriceFeedDataV1 {
price_feed_id: PriceFeedId(1),
source_timestamp_us: TimestampUs::from_micros(2),
publisher_timestamp_us: TimestampUs::from_micros(3),
price: Some(Price::from_nonzero_mantissa(4.try_into().unwrap())),
best_bid_price: None,
best_ask_price: None,
};
assert_eq!(
bincode::serde::decode_from_slice::<PriceFeedDataV1, _>(&data2, bincode::config::legacy())
.unwrap()
.0,
expected2
);
assert_eq!(
bincode::serde::encode_to_vec(&expected2, bincode::config::legacy()).unwrap(),
data2
);
}
#[test]
fn price_feed_data_v2_serde() {
let data = [
1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 6, 2, 0, 0, 0, 0, 0, 0, 0, ];
let expected = PriceFeedDataV2 {
price_feed_id: PriceFeedId(1),
source_timestamp_us: TimestampUs::from_micros(2),
publisher_timestamp_us: TimestampUs::from_micros(3),
price: Some(Price::from_nonzero_mantissa(4.try_into().unwrap())),
best_bid_price: Some(Price::from_nonzero_mantissa(5.try_into().unwrap())),
best_ask_price: Some(Price::from_nonzero_mantissa(
(2 * 256 + 6).try_into().unwrap(),
)),
funding_rate: None,
};
assert_eq!(
bincode::serde::decode_from_slice::<PriceFeedDataV2, _>(&data, bincode::config::legacy())
.unwrap()
.0,
expected
);
assert_eq!(
bincode::serde::encode_to_vec(&expected, bincode::config::legacy()).unwrap(),
data
);
let data2 = [
1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 3, 0, 0, 0, 0, 0, 0, ];
let expected2 = PriceFeedDataV2 {
price_feed_id: PriceFeedId(1),
source_timestamp_us: TimestampUs::from_micros(2),
publisher_timestamp_us: TimestampUs::from_micros(3),
price: Some(Price::from_nonzero_mantissa(4.try_into().unwrap())),
best_bid_price: None,
best_ask_price: None,
funding_rate: Some(Rate::from_mantissa(3 * 256 + 7)),
};
assert_eq!(
bincode::serde::decode_from_slice::<PriceFeedDataV2, _>(&data2, bincode::config::legacy())
.unwrap()
.0,
expected2
);
assert_eq!(
bincode::serde::encode_to_vec(&expected2, bincode::config::legacy()).unwrap(),
data2
);
}