1pub mod api;
5pub mod binary_update;
7mod dynamic_value;
8mod feed_kind;
9pub mod jrpc;
11pub mod message;
13pub mod payload;
15mod price;
16pub mod publisher;
18mod rate;
19mod serde_price_as_i64;
20mod serde_str;
21mod symbol_state;
22pub mod time;
24
25use derive_more::derive::{From, Into};
26use serde::{Deserialize, Serialize};
27
28pub use crate::{
29    dynamic_value::DynamicValue,
30    feed_kind::FeedKind,
31    price::{Price, PriceError},
32    rate::{Rate, RateError},
33    symbol_state::SymbolState,
34};
35
36#[derive(
37    Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, From, Into,
38)]
39pub struct PublisherId(pub u16);
40
41#[derive(
42    Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, From, Into,
43)]
44pub struct PriceFeedId(pub u32);
45
46#[derive(
47    Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, From, Into,
48)]
49pub struct ChannelId(pub u8);
50
51impl ChannelId {
52    pub const REAL_TIME: ChannelId = ChannelId(1);
53    pub const FIXED_RATE_50: ChannelId = ChannelId(2);
54    pub const FIXED_RATE_200: ChannelId = ChannelId(3);
55    pub const FIXED_RATE_1000: ChannelId = ChannelId(4);
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
59#[serde(rename_all = "camelCase")]
60pub enum PriceFeedProperty {
61    Price,
62    BestBidPrice,
63    BestAskPrice,
64    PublisherCount,
65    Exponent,
66    Confidence,
67    FundingRate,
68    FundingTimestamp,
69    FundingRateInterval,
70    }
72
73enum ExponentFactor {
75    Mul(i64),
77    Div(i64),
79}
80
81impl ExponentFactor {
82    fn get(exponent: i16) -> Option<Self> {
83        if exponent >= 0 {
84            let exponent: u32 = exponent.try_into().ok()?;
85            Some(ExponentFactor::Div(10_i64.checked_pow(exponent)?))
86        } else {
87            let minus_exponent: u32 = exponent.checked_neg()?.try_into().ok()?;
88            Some(ExponentFactor::Mul(10_i64.checked_pow(minus_exponent)?))
89        }
90    }
91}
92
93#[test]
94fn magics_in_big_endian() {
95    use crate::{
96        binary_update::BINARY_UPDATE_FORMAT_MAGIC,
97        message::format_magics_le::{
98            EVM_FORMAT_MAGIC, JSON_FORMAT_MAGIC, LE_ECDSA_FORMAT_MAGIC, LE_UNSIGNED_FORMAT_MAGIC,
99            SOLANA_FORMAT_MAGIC,
100        },
101        payload::PAYLOAD_FORMAT_MAGIC,
102    };
103
104    assert_eq!(u32::swap_bytes(BINARY_UPDATE_FORMAT_MAGIC), 1937213467);
108    assert_eq!(u32::swap_bytes(PAYLOAD_FORMAT_MAGIC), 1976813459);
109
110    assert_eq!(u32::swap_bytes(SOLANA_FORMAT_MAGIC), 3103857282);
111    assert_eq!(u32::swap_bytes(JSON_FORMAT_MAGIC), 2584795844);
112    assert_eq!(u32::swap_bytes(EVM_FORMAT_MAGIC), 706910618);
113    assert_eq!(u32::swap_bytes(LE_ECDSA_FORMAT_MAGIC), 3837609805);
114    assert_eq!(u32::swap_bytes(LE_UNSIGNED_FORMAT_MAGIC), 206398297);
115
116    for magic in [
117        BINARY_UPDATE_FORMAT_MAGIC,
118        PAYLOAD_FORMAT_MAGIC,
119        SOLANA_FORMAT_MAGIC,
120        JSON_FORMAT_MAGIC,
121        EVM_FORMAT_MAGIC,
122        LE_ECDSA_FORMAT_MAGIC,
123        LE_UNSIGNED_FORMAT_MAGIC,
124    ] {
125        assert_ne!(u32::swap_bytes(magic), magic);
127    }
128}