rusty_feeder/exchange/upbit/data/
subscription_converter.rs

1//! UpbitSubscriptionConverter - Conversion between standardized options and Upbit-specific formats
2//!
3//! This module provides functions to convert from the standardized SubscriptionOptions
4//! structure to Upbit-specific subscription formats.
5
6use simd_json::OwnedValue as Value;
7use smallvec::SmallVec;
8use smartstring::alias::String;
9
10use crate::provider::prelude::*;
11
12/// Convert from standardized SubscriptionOptions to Upbit subscription format
13#[inline]
14pub fn options_to_upbit_subscription(options: &SubscriptionOptions) -> Vec<Value> {
15    match options.subscription_type {
16        SubscriptionType::Trade => create_trade_subscription(
17            &options.id,
18            options.symbols.clone(),
19            Some(options.snapshot_only),
20            Some(options.realtime_only),
21            options.format.as_deref() == Some("SIMPLE"),
22        ),
23        SubscriptionType::OrderBook => create_orderbook_subscription(
24            &options.id,
25            options.symbols.clone(),
26            Some(options.snapshot_only),
27            Some(options.realtime_only),
28            options.format.as_deref() == Some("SIMPLE"),
29            None, // No level parameter in SubscriptionOptions
30        ),
31        SubscriptionType::Ticker => create_ticker_subscription(
32            &options.id,
33            options.symbols.clone(),
34            Some(options.snapshot_only),
35            Some(options.realtime_only),
36            options.format.as_deref() == Some("SIMPLE"),
37        ),
38        _ => Vec::new(), // Upbit doesn't support other subscription types natively
39    }
40}
41
42/// Create a trade subscription array for Upbit WebSocket
43#[inline]
44pub fn create_trade_subscription(
45    ticket: &str,
46    symbols: SmallVec<[String; 8]>,
47    is_only_snapshot: Option<bool>,
48    is_only_realtime: Option<bool>,
49    use_simple_format: bool,
50) -> Vec<Value> {
51    let mut result = SmallVec::<[Value; 3]>::new();
52
53    // Add ticket (correlation id)
54    result.push(simd_json::json!({
55        "ticket": ticket,
56    }));
57
58    // Add format if using simple format
59    if use_simple_format {
60        result.push(simd_json::json!({
61            "format": "SIMPLE"
62        }));
63    }
64
65    // Add trade stream subscription
66    let mut trade_sub = simd_json::json!({
67        "type": "trade",
68        "codes": symbols.to_vec(),
69    });
70
71    // Add snapshot/realtime flags if provided
72    if let Some(snapshot) = is_only_snapshot {
73        trade_sub["isOnlySnapshot"] = simd_json::json!(snapshot);
74    }
75
76    if let Some(realtime) = is_only_realtime {
77        trade_sub["isOnlyRealtime"] = simd_json::json!(realtime);
78    }
79
80    result.push(trade_sub);
81
82    result.into_vec()
83}
84
85/// Create an orderbook subscription array for Upbit WebSocket
86#[inline]
87pub fn create_orderbook_subscription(
88    ticket: &str,
89    symbols: SmallVec<[String; 8]>,
90    is_only_snapshot: Option<bool>,
91    is_only_realtime: Option<bool>,
92    use_simple_format: bool,
93    level: Option<f64>,
94) -> Vec<Value> {
95    let mut result = SmallVec::<[Value; 3]>::new();
96
97    // Add ticket (correlation id)
98    result.push(simd_json::json!({
99        "ticket": ticket,
100    }));
101
102    // Add format if using simple format
103    if use_simple_format {
104        result.push(simd_json::json!({
105            "format": "SIMPLE"
106        }));
107    }
108
109    // Add orderbook stream subscription
110    let mut orderbook_sub = simd_json::json!({
111        "type": "orderbook",
112        "codes": symbols.to_vec(),
113    });
114
115    // Add snapshot/realtime flags if provided
116    if let Some(snapshot) = is_only_snapshot {
117        orderbook_sub["isOnlySnapshot"] = simd_json::json!(snapshot);
118    }
119
120    if let Some(realtime) = is_only_realtime {
121        orderbook_sub["isOnlyRealtime"] = simd_json::json!(realtime);
122    }
123
124    // Add level if provided (for orderbook aggregation)
125    if let Some(level_value) = level {
126        orderbook_sub["level"] = simd_json::json!(level_value);
127    }
128
129    result.push(orderbook_sub);
130
131    result.into_vec()
132}
133
134/// Create a ticker subscription array for Upbit WebSocket
135#[inline]
136pub fn create_ticker_subscription(
137    ticket: &str,
138    symbols: SmallVec<[String; 8]>,
139    is_only_snapshot: Option<bool>,
140    is_only_realtime: Option<bool>,
141    use_simple_format: bool,
142) -> Vec<Value> {
143    let mut result = SmallVec::<[Value; 3]>::new();
144
145    // Add ticket (correlation id)
146    result.push(simd_json::json!({
147        "ticket": ticket,
148    }));
149
150    // Add format if using simple format
151    if use_simple_format {
152        result.push(simd_json::json!({
153            "format": "SIMPLE"
154        }));
155    }
156
157    // Add ticker stream subscription
158    let mut ticker_sub = simd_json::json!({
159        "type": "ticker",
160        "codes": symbols.to_vec(),
161    });
162
163    // Add snapshot/realtime flags if provided
164    if let Some(snapshot) = is_only_snapshot {
165        ticker_sub["isOnlySnapshot"] = simd_json::json!(snapshot);
166    }
167
168    if let Some(realtime) = is_only_realtime {
169        ticker_sub["isOnlyRealtime"] = simd_json::json!(realtime);
170    }
171
172    result.push(ticker_sub);
173
174    result.into_vec()
175}