@@ -4,22 +4,20 @@ use crate::time::TimestampUs;
44use crate :: FeedKind ;
55use crate :: { symbol_state:: SymbolState , PriceFeedId , SymbolV3 } ;
66use serde:: { Deserialize , Serialize } ;
7- use strum:: { Display , EnumString } ;
87
98/// The pricing context or type of instrument for a feed.
10- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Serialize , Deserialize , Display , EnumString ) ]
9+ /// This is an internal type and should not be used by clients as it is non-exhaustive.
10+ /// The API response can evolve to contain additional variants that are not listed here.
11+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Serialize , Deserialize ) ]
1112#[ serde( rename_all = "lowercase" ) ]
12- #[ strum( serialize_all = "lowercase" ) ]
1313pub enum InstrumentType {
1414 /// Spot price
1515 Spot ,
1616 /// Redemption rate
1717 #[ serde( rename = "redemptionrate" ) ]
18- #[ strum( serialize = "redemptionrate" ) ]
1918 RedemptionRate ,
2019 /// Funding rate
2120 #[ serde( rename = "fundingrate" ) ]
22- #[ strum( serialize = "fundingrate" ) ]
2321 FundingRate ,
2422 /// Future price
2523 Future ,
@@ -30,6 +28,8 @@ pub enum InstrumentType {
3028}
3129
3230/// High-level asset class.
31+ /// This is an internal type and should not be used by clients as it is non-exhaustive.
32+ /// The API response can evolve to contain additional variants that are not listed here.
3333#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Serialize , Deserialize ) ]
3434#[ serde( rename_all = "kebab-case" ) ]
3535pub enum AssetClass {
@@ -43,12 +43,8 @@ pub enum AssetClass {
4343 Metal ,
4444 /// Rates
4545 Rates ,
46- /// Net Asset Value
47- Nav ,
4846 /// Commodity
4947 Commodity ,
50- /// Funding rate
51- FundingRate ,
5248}
5349
5450/// Feed metadata as returned by the v3 metadata API.
@@ -73,9 +69,9 @@ pub struct FeedResponseV3 {
7369 /// The Asset ID of the quote asset.
7470 /// Example: `"USD"`
7571 pub quote_asset_id : String ,
76- /// The pricing context.
72+ /// The pricing context. Should be one of the values in the InstrumentType enum.
7773 /// Example: `"spot"`
78- pub instrument_type : InstrumentType ,
74+ pub instrument_type : String ,
7975 /// Aggregator or producer of the prices.
8076 /// Examples: `"pyth"`, `"binance"`
8177 pub source : String ,
@@ -95,8 +91,9 @@ pub struct FeedResponseV3 {
9591 /// Example: `"active"`
9692 pub state : SymbolState ,
9793 /// High-level asset class. One of crypto, fx, equity, metal, rates, nav, commodity, funding-rate.
94+ /// Should be one of the values in the AssetClass enum.
9895 /// Example: `"crypto"`
99- pub asset_type : AssetClass ,
96+ pub asset_type : String ,
10097 /// CoinMarketCap asset identifier.
10198 /// Example: `"123"`
10299 #[ serde( skip_serializing_if = "Option::is_none" ) ]
@@ -131,7 +128,7 @@ pub struct AssetResponseV3 {
131128 pub full_name : String ,
132129 /// High-level asset class.
133130 /// Example: `"crypto"`
134- pub class : AssetClass ,
131+ pub class : String ,
135132 /// More granular categorization within class.
136133 /// Example: `"stablecoin"`
137134 #[ serde( skip_serializing_if = "Option::is_none" ) ]
@@ -146,37 +143,15 @@ pub struct AssetResponseV3 {
146143mod tests {
147144 use super :: * ;
148145
149- #[ test]
150- fn test_instrument_type_roundtrip ( ) {
151- let types = vec ! [
152- InstrumentType :: Spot ,
153- InstrumentType :: RedemptionRate ,
154- InstrumentType :: FundingRate ,
155- InstrumentType :: Future ,
156- InstrumentType :: Nav ,
157- InstrumentType :: Twap ,
158- ] ;
159-
160- for instrument_type in types {
161- let string_repr = instrument_type. to_string ( ) ;
162- let parsed = string_repr. parse :: < InstrumentType > ( ) . unwrap ( ) ;
163- assert_eq ! ( parsed, instrument_type) ;
164- }
165-
166- // Test invalid values
167- assert ! ( "invalid" . parse:: <InstrumentType >( ) . is_err( ) ) ;
168- assert ! ( "SPOT" . parse:: <InstrumentType >( ) . is_err( ) ) ; // case sensitive
169- }
170-
171146 #[ test]
172147 fn test_feed_response_v3_roundtrip ( ) {
173148 use crate :: { symbol_state:: SymbolState , FeedKind , PriceFeedId } ;
174149
175150 let symbol = SymbolV3 :: new (
176151 "pyth" . to_string ( ) ,
177- InstrumentType :: Spot ,
152+ "spot" . to_string ( ) ,
178153 "btc" . to_string ( ) ,
179- "usd" . to_string ( ) ,
154+ Some ( "usd" . to_string ( ) ) ,
180155 ) ;
181156
182157 let feed_response = FeedResponseV3 {
@@ -186,14 +161,14 @@ mod tests {
186161 description : "Pyth Network Aggregate Price for spot BTC/USD" . to_string ( ) ,
187162 base_asset_id : "BTC" . to_string ( ) ,
188163 quote_asset_id : "USD" . to_string ( ) ,
189- instrument_type : InstrumentType :: Spot ,
164+ instrument_type : "spot" . to_string ( ) ,
190165 source : "pyth" . to_string ( ) ,
191166 schedule : "America/New_York;O,O,O,O,O,O,O;" . to_string ( ) ,
192167 exponent : -8 ,
193168 update_interval_seconds : 10 ,
194169 min_publishers : 3 ,
195170 state : SymbolState :: Stable ,
196- asset_type : AssetClass :: Crypto ,
171+ asset_type : "crypto" . to_string ( ) ,
197172 cmc_id : Some ( "1" . to_string ( ) ) ,
198173 pythnet_id : "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43"
199174 . to_string ( ) ,
@@ -212,9 +187,9 @@ mod tests {
212187 serde_json:: from_str ( & json) . expect ( "Failed to deserialize FeedResponseV3" ) ;
213188 assert_eq ! ( deserialized. symbol. as_string( ) , "pyth.spot.btc/usd" ) ;
214189 assert_eq ! ( deserialized. symbol. source, "pyth" ) ;
215- assert_eq ! ( deserialized. symbol. instrument_type, InstrumentType :: Spot ) ;
190+ assert_eq ! ( deserialized. symbol. instrument_type, "spot" ) ;
216191 assert_eq ! ( deserialized. symbol. base, "btc" ) ;
217- assert_eq ! ( deserialized. symbol. quote, "usd" ) ;
192+ assert_eq ! ( deserialized. symbol. quote, Some ( "usd" . to_string ( ) ) ) ;
218193
219194 // Ensure the entire structure matches
220195 assert_eq ! ( deserialized, feed_response) ;
0 commit comments