hyperflow_rs_models/
lib.rs

1//! Hyperflow Rust Models
2//! 
3//! This crate provides generated models from Protocol Buffers definitions.
4
5pub mod models {
6    #![allow(warnings)]
7    include!(concat!(env!("OUT_DIR"), "/hyperflow.core.v1.rs"));
8}
9
10#[cfg(test)]
11mod tests {
12    use super::models::{HyperliquidTrade, RawTrade, MarketType, EnrichedTrade, Position};
13    use prost::Message;
14
15    #[test]
16    fn test_create_hyperliquid_trade() {
17        let trade = HyperliquidTrade {
18            coin: "ETH".to_string(),
19            side: "buy".to_string(),
20            px: "123.45".to_string(),
21            sz: "1.0".to_string(),
22            hash: "0xabc123".to_string(),
23            time: 1678886400,
24            tid: 1,
25            users: vec!["buyer_address".to_string(), "seller_address".to_string()],
26        };
27
28        assert_eq!(trade.coin, "ETH");
29        assert_eq!(trade.side, "buy");
30        assert_eq!(trade.px, "123.45");
31        assert_eq!(trade.sz, "1.0");
32        assert_eq!(trade.hash, "0xabc123");
33        assert_eq!(trade.time, 1678886400);
34        assert_eq!(trade.tid, 1);
35        assert_eq!(trade.users, vec!["buyer_address", "seller_address"]);
36    }
37
38    #[test]
39    fn test_hyperliquid_trade_serialization() {
40        let trade = HyperliquidTrade {
41            coin: "BTC".to_string(),
42            side: "sell".to_string(),
43            px: "456.78".to_string(),
44            sz: "0.5".to_string(),
45            hash: "0xdef456".to_string(),
46            time: 1678886500,
47            tid: 2,
48            users: vec!["userA".to_string(), "userB".to_string()],
49        };
50
51        let mut buf = Vec::new();
52        trade.encode(&mut buf).unwrap();
53        let deserialized_trade = HyperliquidTrade::decode(&buf[..]).unwrap();
54
55        assert_eq!(deserialized_trade.coin, "BTC");
56        assert_eq!(deserialized_trade.side, "sell");
57        assert_eq!(deserialized_trade.px, "456.78");
58        assert_eq!(deserialized_trade.sz, "0.5");
59        assert_eq!(deserialized_trade.hash, "0xdef456");
60        assert_eq!(deserialized_trade.time, 1678886500);
61        assert_eq!(deserialized_trade.tid, 2);
62        assert_eq!(deserialized_trade.users, vec!["userA", "userB"]);
63    }
64
65    #[test]
66    fn test_create_raw_trade() {
67        let raw_trade = RawTrade {
68            symbol: "BTC/USD".to_string(),
69            is_buy: true,
70            is_taker: false,
71            price: "50000.0".to_string(),
72            amount: "0.1".to_string(),
73            quote_amount: "5000.0".to_string(),
74            trade_id: "abc-123".to_string(),
75            event_at: 1678887000,
76            transaction_id: "ext-xyz".to_string(),
77            wallet_address: "0x12345".to_string(),
78            market_type: MarketType::Perp as i32,
79        };
80
81        assert_eq!(raw_trade.symbol, "BTC/USD");
82        assert!(raw_trade.is_buy);
83        assert!(!raw_trade.is_taker);
84        assert_eq!(raw_trade.price, "50000.0");
85        assert_eq!(raw_trade.amount, "0.1");
86        assert_eq!(raw_trade.quote_amount, "5000.0");
87        assert_eq!(raw_trade.trade_id, "abc-123");
88        assert_eq!(raw_trade.event_at, 1678887000);
89        assert_eq!(raw_trade.transaction_id, "ext-xyz");
90        assert_eq!(raw_trade.wallet_address, "0x12345");
91        assert_eq!(raw_trade.market_type, MarketType::Perp as i32);
92    }
93
94    #[test]
95    fn test_raw_trade_serialization() {
96        let raw_trade = RawTrade {
97            symbol: "ETH/USD".to_string(),
98            is_buy: false,
99            is_taker: true,
100            price: "2000.0".to_string(),
101            amount: "0.5".to_string(),
102            quote_amount: "1000.0".to_string(),
103            trade_id: "def-456".to_string(),
104            event_at: 1678887100,
105            transaction_id: "ext-uvw".to_string(),
106            wallet_address: "0x67890".to_string(),
107            market_type: MarketType::Spot as i32,
108        };
109
110        let mut buf = Vec::new();
111        raw_trade.encode(&mut buf).unwrap();
112        let deserialized_raw_trade = RawTrade::decode(&buf[..]).unwrap();
113
114        assert_eq!(deserialized_raw_trade.symbol, "ETH/USD");
115        assert!(!deserialized_raw_trade.is_buy);
116        assert!(deserialized_raw_trade.is_taker);
117        assert_eq!(deserialized_raw_trade.price, "2000.0");
118        assert_eq!(deserialized_raw_trade.amount, "0.5");
119        assert_eq!(deserialized_raw_trade.quote_amount, "1000.0");
120        assert_eq!(deserialized_raw_trade.trade_id, "def-456");
121        assert_eq!(deserialized_raw_trade.event_at, 1678887100);
122        assert_eq!(deserialized_raw_trade.transaction_id, "ext-uvw");
123        assert_eq!(deserialized_raw_trade.wallet_address, "0x67890");
124        assert_eq!(deserialized_raw_trade.market_type, MarketType::Spot as i32);
125    }
126
127    #[test]
128    fn test_hyperliquid_trade_default_values() {
129        let trade = HyperliquidTrade::default();
130        assert_eq!(trade.coin, "");
131        assert_eq!(trade.side, "");
132        assert_eq!(trade.px, "");
133        assert_eq!(trade.sz, "");
134        assert_eq!(trade.hash, "");
135        assert_eq!(trade.time, 0);
136        assert_eq!(trade.tid, 0);
137        assert!(trade.users.is_empty());
138    }
139
140    #[test]
141    fn test_create_hyperliquid_trade_zero_values() {
142        let trade = HyperliquidTrade {
143            px: "0.0".to_string(),
144            sz: "0.0".to_string(),
145            users: vec!["buyer_address".to_string()],
146            ..Default::default()
147        };
148        assert_eq!(trade.px, "0.0");
149        assert_eq!(trade.sz, "0.0");
150        assert_eq!(trade.users, vec!["buyer_address"]);
151    }
152
153    #[test]
154    fn test_raw_trade_default_values() {
155        let raw_trade = RawTrade::default();
156        assert_eq!(raw_trade.symbol, "");
157        assert!(!raw_trade.is_buy);
158        assert!(!raw_trade.is_taker);
159        assert_eq!(raw_trade.price, "");
160        assert_eq!(raw_trade.amount, "");
161        assert_eq!(raw_trade.quote_amount, "");
162        assert_eq!(raw_trade.trade_id, "");
163        assert_eq!(raw_trade.event_at, 0);
164        assert_eq!(raw_trade.transaction_id, "");
165        assert_eq!(raw_trade.wallet_address, "");
166        assert_eq!(raw_trade.market_type, MarketType::Perp as i32); // Default for enums is the first non-unspecified value
167    }
168
169    #[test]
170    fn test_create_raw_trade_zero_values() {
171        let raw_trade = RawTrade {
172            price: "0.0".to_string(),
173            amount: "0.0".to_string(),
174            quote_amount: "0.0".to_string(),
175            transaction_id: "".to_string(),
176            wallet_address: "".to_string(),
177            market_type: MarketType::Perp as i32,
178            ..Default::default()
179        };
180        assert_eq!(raw_trade.price, "0.0");
181        assert_eq!(raw_trade.amount, "0.0");
182        assert_eq!(raw_trade.quote_amount, "0.0");
183        assert_eq!(raw_trade.transaction_id, "");
184        assert_eq!(raw_trade.wallet_address, "");
185    }
186
187    #[test]
188    fn test_raw_trade_serialization_all_market_types() {
189        let market_types = [
190            MarketType::Perp,
191            MarketType::Spot,
192        ];
193        for mt in market_types.iter() {
194            let raw_trade = RawTrade {
195                symbol: "XRP/USD".to_string(),
196                is_buy: true,
197                is_taker: false,
198                price: "0.5".to_string(),
199                amount: "100.0".to_string(),
200                quote_amount: "50.0".to_string(),
201                trade_id: "test-id".to_string(),
202                event_at: 1678887300,
203                transaction_id: "ext-test".to_string(),
204                wallet_address: "0xabcde".to_string(),
205                market_type: *mt as i32,
206            };
207
208            let mut buf = Vec::new();
209            raw_trade.encode(&mut buf).unwrap();
210            let deserialized_raw_trade = RawTrade::decode(&buf[..]).unwrap();
211            assert_eq!(deserialized_raw_trade.market_type, *mt as i32);
212        }
213    }
214
215    #[test]
216    fn test_market_type_enum() {
217        assert_eq!(MarketType::Perp as i32, 0); // Corrected based on proto definition
218        assert_eq!(MarketType::Spot as i32, 1); // Corrected based on proto definition
219    }
220
221    #[test]
222    fn test_create_enriched_trade() {
223        let enriched_trade = EnrichedTrade {
224            symbol: "BTC/USD".to_string(),
225            is_buy: true,
226            is_taker: false,
227            price: "50000.0".to_string(),
228            amount: "0.1".to_string(),
229            quote_amount: "5000.0".to_string(),
230            trade_id: "abc-123".to_string(),
231            event_at: 1678887000,
232            transaction_id: "ext-xyz".to_string(),
233            wallet_address: "0x12345".to_string(),
234            market_type: MarketType::Perp as i32,
235            pnl: "100.0".to_string(),
236            pnl_usd: "100.0".to_string(),
237            holding_duration: 3600,
238        };
239
240        assert_eq!(enriched_trade.symbol, "BTC/USD");
241        assert!(enriched_trade.is_buy);
242        assert!(!enriched_trade.is_taker);
243        assert_eq!(enriched_trade.price, "50000.0");
244        assert_eq!(enriched_trade.amount, "0.1");
245        assert_eq!(enriched_trade.quote_amount, "5000.0");
246        assert_eq!(enriched_trade.trade_id, "abc-123");
247        assert_eq!(enriched_trade.event_at, 1678887000);
248        assert_eq!(enriched_trade.transaction_id, "ext-xyz");
249        assert_eq!(enriched_trade.wallet_address, "0x12345");
250        assert_eq!(enriched_trade.market_type, MarketType::Perp as i32);
251        assert_eq!(enriched_trade.pnl, "100.0");
252        assert_eq!(enriched_trade.pnl_usd, "100.0");
253        assert_eq!(enriched_trade.holding_duration, 3600);
254    }
255
256    #[test]
257    fn test_enriched_trade_default_values() {
258        let enriched_trade = EnrichedTrade::default();
259        assert_eq!(enriched_trade.symbol, "");
260        assert!(!enriched_trade.is_buy);
261        assert!(!enriched_trade.is_taker);
262        assert_eq!(enriched_trade.price, "");
263        assert_eq!(enriched_trade.amount, "");
264        assert_eq!(enriched_trade.quote_amount, "");
265        assert_eq!(enriched_trade.trade_id, "");
266        assert_eq!(enriched_trade.event_at, 0);
267        assert_eq!(enriched_trade.transaction_id, "");
268        assert_eq!(enriched_trade.wallet_address, "");
269        assert_eq!(enriched_trade.market_type, MarketType::Perp as i32);
270        assert_eq!(enriched_trade.pnl, "");
271        assert_eq!(enriched_trade.pnl_usd, "");
272        assert_eq!(enriched_trade.holding_duration, 0);
273    }
274
275    #[test]
276    fn test_enriched_trade_serialization() {
277        let enriched_trade = EnrichedTrade {
278            symbol: "ETH/USD".to_string(),
279            is_buy: false,
280            is_taker: true,
281            price: "2000.0".to_string(),
282            amount: "0.5".to_string(),
283            quote_amount: "1000.0".to_string(),
284            trade_id: "def-456".to_string(),
285            event_at: 1678887100,
286            transaction_id: "ext-uvw".to_string(),
287            wallet_address: "0x67890".to_string(),
288            market_type: MarketType::Spot as i32,
289            pnl: "-50.0".to_string(),
290            pnl_usd: "-50.0".to_string(),
291            holding_duration: 7200,
292        };
293
294        let mut buf = Vec::new();
295        enriched_trade.encode(&mut buf).unwrap();
296        let deserialized_enriched_trade = EnrichedTrade::decode(&buf[..]).unwrap();
297
298        assert_eq!(deserialized_enriched_trade.symbol, "ETH/USD");
299        assert!(!deserialized_enriched_trade.is_buy);
300        assert!(deserialized_enriched_trade.is_taker);
301        assert_eq!(deserialized_enriched_trade.price, "2000.0");
302        assert_eq!(deserialized_enriched_trade.amount, "0.5");
303        assert_eq!(deserialized_enriched_trade.quote_amount, "1000.0");
304        assert_eq!(deserialized_enriched_trade.trade_id, "def-456");
305        assert_eq!(deserialized_enriched_trade.event_at, 1678887100);
306        assert_eq!(deserialized_enriched_trade.transaction_id, "ext-uvw");
307        assert_eq!(deserialized_enriched_trade.wallet_address, "0x67890");
308        assert_eq!(deserialized_enriched_trade.market_type, MarketType::Spot as i32);
309        assert_eq!(deserialized_enriched_trade.pnl, "-50.0");
310        assert_eq!(deserialized_enriched_trade.pnl_usd, "-50.0");
311        assert_eq!(deserialized_enriched_trade.holding_duration, 7200);
312    }
313
314    #[test]
315    fn test_create_enriched_trade_zero_values() {
316        let enriched_trade = EnrichedTrade {
317            price: "0.0".to_string(),
318            amount: "0.0".to_string(),
319            quote_amount: "0.0".to_string(),
320            transaction_id: "".to_string(),
321            wallet_address: "".to_string(),
322            market_type: MarketType::Perp as i32,
323            pnl: "0.0".to_string(),
324            pnl_usd: "0.0".to_string(),
325            holding_duration: 0,
326            ..Default::default()
327        };
328        assert_eq!(enriched_trade.price, "0.0");
329        assert_eq!(enriched_trade.amount, "0.0");
330        assert_eq!(enriched_trade.quote_amount, "0.0");
331        assert_eq!(enriched_trade.transaction_id, "");
332        assert_eq!(enriched_trade.wallet_address, "");
333        assert_eq!(enriched_trade.pnl, "0.0");
334        assert_eq!(enriched_trade.pnl_usd, "0.0");
335        assert_eq!(enriched_trade.holding_duration, 0);
336    }
337
338    #[test]
339    fn test_create_position() {
340        let position = Position {
341            symbol: "BTC/USD".to_string(),
342            is_buy: true,
343            average_price: "50000.0".to_string(),
344            amount: "0.1".to_string(),
345            quote_amount: "5000.0".to_string(),
346            wallet_address: "0x12345".to_string(),
347            market_type: MarketType::Perp as i32,
348            holding_duration: 3600,
349        };
350
351        assert_eq!(position.symbol, "BTC/USD");
352        assert!(position.is_buy);
353        assert_eq!(position.average_price, "50000.0");
354        assert_eq!(position.amount, "0.1");
355        assert_eq!(position.quote_amount, "5000.0");
356        assert_eq!(position.wallet_address, "0x12345");
357        assert_eq!(position.market_type, MarketType::Perp as i32);
358        assert_eq!(position.holding_duration, 3600);
359    }
360
361    #[test]
362    fn test_position_default_values() {
363        let position = Position::default();
364        assert_eq!(position.symbol, "");
365        assert!(!position.is_buy);
366        assert_eq!(position.average_price, "");
367        assert_eq!(position.amount, "");
368        assert_eq!(position.quote_amount, "");
369        assert_eq!(position.wallet_address, "");
370        assert_eq!(position.market_type, MarketType::Perp as i32);
371        assert_eq!(position.holding_duration, 0);
372    }
373
374    #[test]
375    fn test_position_serialization() {
376        let position = Position {
377            symbol: "ETH/USD".to_string(),
378            is_buy: false,
379            average_price: "2000.0".to_string(),
380            amount: "0.5".to_string(),
381            quote_amount: "1000.0".to_string(),
382            wallet_address: "0x67890".to_string(),
383            market_type: MarketType::Spot as i32,
384            holding_duration: 7200,
385        };
386
387        let mut buf = Vec::new();
388        position.encode(&mut buf).unwrap();
389        let deserialized_position = Position::decode(&buf[..]).unwrap();
390
391        assert_eq!(deserialized_position.symbol, "ETH/USD");
392        assert!(!deserialized_position.is_buy);
393        assert_eq!(deserialized_position.average_price, "2000.0");
394        assert_eq!(deserialized_position.amount, "0.5");
395        assert_eq!(deserialized_position.quote_amount, "1000.0");
396        assert_eq!(deserialized_position.wallet_address, "0x67890");
397        assert_eq!(deserialized_position.market_type, MarketType::Spot as i32);
398        assert_eq!(deserialized_position.holding_duration, 7200);
399    }
400
401    #[test]
402    fn test_create_position_zero_values() {
403        let position = Position {
404            average_price: "0.0".to_string(),
405            amount: "0.0".to_string(),
406            quote_amount: "0.0".to_string(),
407            wallet_address: "".to_string(),
408            market_type: MarketType::Perp as i32,
409            holding_duration: 0,
410            ..Default::default()
411        };
412        assert_eq!(position.average_price, "0.0");
413        assert_eq!(position.amount, "0.0");
414        assert_eq!(position.quote_amount, "0.0");
415        assert_eq!(position.wallet_address, "");
416        assert_eq!(position.holding_duration, 0);
417    }
418}