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};
27use utoipa::ToSchema;
28
29pub use crate::{
30 dynamic_value::DynamicValue,
31 feed_kind::FeedKind,
32 price::{Price, PriceError},
33 rate::{Rate, RateError},
34 symbol_state::SymbolState,
35};
36
37#[derive(
38 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, From, Into,
39)]
40pub struct AssetId(pub u32);
41
42#[derive(
43 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, From, Into,
44)]
45pub struct PublisherId(pub u16);
46
47#[derive(
48 Debug,
49 Clone,
50 Copy,
51 PartialEq,
52 Eq,
53 Hash,
54 PartialOrd,
55 Ord,
56 Serialize,
57 Deserialize,
58 From,
59 Into,
60 ToSchema,
61)]
62#[schema(value_type = u32)]
63pub struct PriceFeedId(pub u32);
64
65#[derive(
66 Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, From, Into,
67)]
68pub struct ChannelId(pub u8);
69
70impl ChannelId {
71 pub const REAL_TIME: ChannelId = ChannelId(1);
72 pub const FIXED_RATE_50: ChannelId = ChannelId(2);
73 pub const FIXED_RATE_200: ChannelId = ChannelId(3);
74 pub const FIXED_RATE_1000: ChannelId = ChannelId(4);
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)]
78#[serde(rename_all = "camelCase")]
79pub enum PriceFeedProperty {
80 Price,
81 BestBidPrice,
82 BestAskPrice,
83 PublisherCount,
84 Exponent,
85 Confidence,
86 FundingRate,
87 FundingTimestamp,
88 FundingRateInterval,
89 }
91
92#[derive(Debug, Clone, Deserialize)]
93#[serde(rename_all = "kebab-case")]
94pub enum AssetClass {
95 Crypto,
96 Fx,
97 Equity,
98 Metal,
99 Rates,
100 Nav,
101 Commodity,
102 FundingRate,
103}
104
105impl AssetClass {
106 pub fn as_str(&self) -> &'static str {
107 match self {
108 AssetClass::Crypto => "crypto",
109 AssetClass::Fx => "fx",
110 AssetClass::Equity => "equity",
111 AssetClass::Metal => "metal",
112 AssetClass::Rates => "rates",
113 AssetClass::Nav => "nav",
114 AssetClass::Commodity => "commodity",
115 AssetClass::FundingRate => "funding-rate",
116 }
117 }
118}
119
120enum ExponentFactor {
122 Mul(i64),
124 Div(i64),
126}
127
128impl ExponentFactor {
129 fn get(exponent: i16) -> Option<Self> {
130 if exponent >= 0 {
131 let exponent: u32 = exponent.try_into().ok()?;
132 Some(ExponentFactor::Div(10_i64.checked_pow(exponent)?))
133 } else {
134 let minus_exponent: u32 = exponent.checked_neg()?.try_into().ok()?;
135 Some(ExponentFactor::Mul(10_i64.checked_pow(minus_exponent)?))
136 }
137 }
138}
139
140#[test]
141fn magics_in_big_endian() {
142 use crate::{
143 binary_update::BINARY_UPDATE_FORMAT_MAGIC,
144 message::format_magics_le::{
145 EVM_FORMAT_MAGIC, JSON_FORMAT_MAGIC, LE_ECDSA_FORMAT_MAGIC, LE_UNSIGNED_FORMAT_MAGIC,
146 SOLANA_FORMAT_MAGIC,
147 },
148 payload::PAYLOAD_FORMAT_MAGIC,
149 };
150
151 assert_eq!(u32::swap_bytes(BINARY_UPDATE_FORMAT_MAGIC), 1937213467);
155 assert_eq!(u32::swap_bytes(PAYLOAD_FORMAT_MAGIC), 1976813459);
156
157 assert_eq!(u32::swap_bytes(SOLANA_FORMAT_MAGIC), 3103857282);
158 assert_eq!(u32::swap_bytes(JSON_FORMAT_MAGIC), 2584795844);
159 assert_eq!(u32::swap_bytes(EVM_FORMAT_MAGIC), 706910618);
160 assert_eq!(u32::swap_bytes(LE_ECDSA_FORMAT_MAGIC), 3837609805);
161 assert_eq!(u32::swap_bytes(LE_UNSIGNED_FORMAT_MAGIC), 206398297);
162
163 for magic in [
164 BINARY_UPDATE_FORMAT_MAGIC,
165 PAYLOAD_FORMAT_MAGIC,
166 SOLANA_FORMAT_MAGIC,
167 JSON_FORMAT_MAGIC,
168 EVM_FORMAT_MAGIC,
169 LE_ECDSA_FORMAT_MAGIC,
170 LE_UNSIGNED_FORMAT_MAGIC,
171 ] {
172 assert_ne!(u32::swap_bytes(magic), magic);
174 }
175}