| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- use {
- crate::{price::Price, rate::Rate, time::TimestampUs, PriceFeedId},
- derive_more::derive::From,
- serde::{Deserialize, Serialize},
- };
- /// Represents a binary (bincode-serialized) stream update sent
- /// from the publisher to the router.
- #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
- #[serde(rename_all = "camelCase")]
- pub struct PriceFeedDataV2 {
- pub price_feed_id: PriceFeedId,
- /// Timestamp of the last update provided by the source of the prices
- /// (like an exchange). If unavailable, this value is set to `publisher_timestamp_us`.
- pub source_timestamp_us: TimestampUs,
- /// Timestamp of the last update provided by the publisher.
- pub publisher_timestamp_us: TimestampUs,
- /// Last known value of the best executable price of this price feed.
- /// `None` if no value is currently available.
- pub price: Option<Price>,
- /// Last known value of the best bid price of this price feed.
- /// `None` if no value is currently available.
- pub best_bid_price: Option<Price>,
- /// Last known value of the best ask price of this price feed.
- /// `None` if no value is currently available.
- pub best_ask_price: Option<Price>,
- /// Last known value of the funding rate of this feed.
- /// `None` if no value is currently available.
- pub funding_rate: Option<Rate>,
- }
- /// Old Represents a binary (bincode-serialized) stream update sent
- /// from the publisher to the router.
- /// Superseded by `PriceFeedData`.
- #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
- #[serde(rename_all = "camelCase")]
- pub struct PriceFeedDataV1 {
- pub price_feed_id: PriceFeedId,
- /// Timestamp of the last update provided by the source of the prices
- /// (like an exchange). If unavailable, this value is set to `publisher_timestamp_us`.
- pub source_timestamp_us: TimestampUs,
- /// Timestamp of the last update provided by the publisher.
- pub publisher_timestamp_us: TimestampUs,
- /// Last known value of the best executable price of this price feed.
- /// `None` if no value is currently available.
- #[serde(with = "crate::serde_price_as_i64")]
- pub price: Option<Price>,
- /// Last known value of the best bid price of this price feed.
- /// `None` if no value is currently available.
- #[serde(with = "crate::serde_price_as_i64")]
- pub best_bid_price: Option<Price>,
- /// Last known value of the best ask price of this price feed.
- /// `None` if no value is currently available.
- #[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,
- }
- }
- }
- /// A response sent from the server to the publisher client.
- /// Currently only serde errors are reported back to the client.
- #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, From)]
- #[serde(tag = "type")]
- #[serde(rename_all = "camelCase")]
- pub enum ServerResponse {
- UpdateDeserializationError(UpdateDeserializationErrorResponse),
- }
- /// Sent to the publisher if the binary data could not be parsed
- #[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, // price_feed_id
- 2, 0, 0, 0, 0, 0, 0, 0, // source_timestamp_us
- 3, 0, 0, 0, 0, 0, 0, 0, // publisher_timestamp_us
- 4, 0, 0, 0, 0, 0, 0, 0, // price
- 5, 0, 0, 0, 0, 0, 0, 0, // best_bid_price
- 6, 2, 0, 0, 0, 0, 0, 0, // best_ask_price
- ];
- 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::deserialize::<PriceFeedDataV1>(&data).unwrap(),
- expected
- );
- assert_eq!(bincode::serialize(&expected).unwrap(), data);
- let data2 = [
- 1, 0, 0, 0, // price_feed_id
- 2, 0, 0, 0, 0, 0, 0, 0, // source_timestamp_us
- 3, 0, 0, 0, 0, 0, 0, 0, // publisher_timestamp_us
- 4, 0, 0, 0, 0, 0, 0, 0, // price
- 0, 0, 0, 0, 0, 0, 0, 0, // best_bid_price
- 0, 0, 0, 0, 0, 0, 0, 0, // best_ask_price
- ];
- 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::deserialize::<PriceFeedDataV1>(&data2).unwrap(),
- expected2
- );
- assert_eq!(bincode::serialize(&expected2).unwrap(), data2);
- }
- #[test]
- fn price_feed_data_v2_serde() {
- let data = [
- 1, 0, 0, 0, // price_feed_id
- 2, 0, 0, 0, 0, 0, 0, 0, // source_timestamp_us
- 3, 0, 0, 0, 0, 0, 0, 0, // publisher_timestamp_us
- 1, 4, 0, 0, 0, 0, 0, 0, 0, // price
- 1, 5, 0, 0, 0, 0, 0, 0, 0, // best_bid_price
- 1, 6, 2, 0, 0, 0, 0, 0, 0, // best_ask_price
- 0, // funding_rate
- ];
- 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::deserialize::<PriceFeedDataV2>(&data).unwrap(),
- expected
- );
- assert_eq!(bincode::serialize(&expected).unwrap(), data);
- let data2 = [
- 1, 0, 0, 0, // price_feed_id
- 2, 0, 0, 0, 0, 0, 0, 0, // source_timestamp_us
- 3, 0, 0, 0, 0, 0, 0, 0, // publisher_timestamp_us
- 1, 4, 0, 0, 0, 0, 0, 0, 0, // price
- 0, // best_bid_price
- 0, // best_ask_price
- 1, 7, 3, 0, 0, 0, 0, 0, 0, // funding_rate
- ];
- 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::deserialize::<PriceFeedDataV2>(&data2).unwrap(),
- expected2
- );
- assert_eq!(bincode::serialize(&expected2).unwrap(), data2);
- }
|