1use crate::presentation::serialization::string_as_float_opt;
2use lightstreamer_rs::subscription::ItemUpdate;
3use pretty_simple_display::{DebugPretty, DisplaySimple};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
9#[serde(rename_all = "UPPERCASE")]
10pub enum DealingFlag {
11 #[default]
13 Closed,
14 Call,
16 Deal,
18 Edit,
20 ClosingOnly,
22 DealNoEdit,
24 Auction,
26 AuctionNoEdit,
28 Suspend,
30}
31
32#[derive(DebugPretty, Clone, DisplaySimple, Serialize, Deserialize, Default)]
35pub struct PriceData {
36 pub item_name: String,
38 pub item_pos: i32,
40 pub fields: PriceFields,
42 pub changed_fields: PriceFields,
44 pub is_snapshot: bool,
46}
47
48#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize, Default)]
50pub struct PriceFields {
51 #[serde(rename = "MID_OPEN")]
53 #[serde(with = "string_as_float_opt")]
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub mid_open: Option<f64>,
56
57 #[serde(rename = "HIGH")]
59 #[serde(with = "string_as_float_opt")]
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub high: Option<f64>,
62
63 #[serde(rename = "LOW")]
65 #[serde(with = "string_as_float_opt")]
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub low: Option<f64>,
68
69 #[serde(rename = "BID")]
71 #[serde(with = "string_as_float_opt")]
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub bid: Option<f64>,
74
75 #[serde(rename = "OFFER")]
77 #[serde(with = "string_as_float_opt")]
78 #[serde(skip_serializing_if = "Option::is_none")]
79 pub offer: Option<f64>,
80
81 #[serde(rename = "CHANGE")]
83 #[serde(with = "string_as_float_opt")]
84 #[serde(skip_serializing_if = "Option::is_none")]
85 pub change: Option<f64>,
86
87 #[serde(rename = "CHANGE_PCT")]
89 #[serde(with = "string_as_float_opt")]
90 #[serde(skip_serializing_if = "Option::is_none")]
91 pub change_pct: Option<f64>,
92
93 #[serde(rename = "MARKET_DELAY")]
95 #[serde(with = "string_as_float_opt")]
96 #[serde(skip_serializing_if = "Option::is_none")]
97 pub market_delay: Option<f64>,
98
99 #[serde(rename = "MARKET_STATE")]
101 #[serde(skip_serializing_if = "Option::is_none")]
102 pub market_state: Option<String>,
103
104 #[serde(rename = "UPDATE_TIME")]
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub update_time: Option<String>,
108
109 #[serde(rename = "BIDQUOTEID")]
111 #[serde(skip_serializing_if = "Option::is_none")]
112 pub bid_quote_id: Option<String>,
113
114 #[serde(rename = "ASKQUOTEID")]
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub ask_quote_id: Option<String>,
118
119 #[serde(rename = "BIDPRICE1")]
122 #[serde(with = "string_as_float_opt")]
123 #[serde(skip_serializing_if = "Option::is_none")]
124 pub bid_price1: Option<f64>,
125
126 #[serde(rename = "BIDPRICE2")]
128 #[serde(with = "string_as_float_opt")]
129 #[serde(skip_serializing_if = "Option::is_none")]
130 pub bid_price2: Option<f64>,
131
132 #[serde(rename = "BIDPRICE3")]
134 #[serde(with = "string_as_float_opt")]
135 #[serde(skip_serializing_if = "Option::is_none")]
136 pub bid_price3: Option<f64>,
137
138 #[serde(rename = "BIDPRICE4")]
140 #[serde(with = "string_as_float_opt")]
141 #[serde(skip_serializing_if = "Option::is_none")]
142 pub bid_price4: Option<f64>,
143
144 #[serde(rename = "BIDPRICE5")]
146 #[serde(with = "string_as_float_opt")]
147 #[serde(skip_serializing_if = "Option::is_none")]
148 pub bid_price5: Option<f64>,
149
150 #[serde(rename = "ASKPRICE1")]
153 #[serde(with = "string_as_float_opt")]
154 #[serde(skip_serializing_if = "Option::is_none")]
155 pub ask_price1: Option<f64>,
156
157 #[serde(rename = "ASKPRICE2")]
159 #[serde(with = "string_as_float_opt")]
160 #[serde(skip_serializing_if = "Option::is_none")]
161 pub ask_price2: Option<f64>,
162
163 #[serde(rename = "ASKPRICE3")]
165 #[serde(with = "string_as_float_opt")]
166 #[serde(skip_serializing_if = "Option::is_none")]
167 pub ask_price3: Option<f64>,
168
169 #[serde(rename = "ASKPRICE4")]
171 #[serde(with = "string_as_float_opt")]
172 #[serde(skip_serializing_if = "Option::is_none")]
173 pub ask_price4: Option<f64>,
174
175 #[serde(rename = "ASKPRICE5")]
177 #[serde(with = "string_as_float_opt")]
178 #[serde(skip_serializing_if = "Option::is_none")]
179 pub ask_price5: Option<f64>,
180
181 #[serde(rename = "BIDSIZE1")]
184 #[serde(with = "string_as_float_opt")]
185 #[serde(skip_serializing_if = "Option::is_none")]
186 pub bid_size1: Option<f64>,
187
188 #[serde(rename = "BIDSIZE2")]
190 #[serde(with = "string_as_float_opt")]
191 #[serde(skip_serializing_if = "Option::is_none")]
192 pub bid_size2: Option<f64>,
193
194 #[serde(rename = "BIDSIZE3")]
196 #[serde(with = "string_as_float_opt")]
197 #[serde(skip_serializing_if = "Option::is_none")]
198 pub bid_size3: Option<f64>,
199
200 #[serde(rename = "BIDSIZE4")]
202 #[serde(with = "string_as_float_opt")]
203 #[serde(skip_serializing_if = "Option::is_none")]
204 pub bid_size4: Option<f64>,
205
206 #[serde(rename = "BIDSIZE5")]
208 #[serde(with = "string_as_float_opt")]
209 #[serde(skip_serializing_if = "Option::is_none")]
210 pub bid_size5: Option<f64>,
211
212 #[serde(rename = "ASKSIZE1")]
215 #[serde(with = "string_as_float_opt")]
216 #[serde(skip_serializing_if = "Option::is_none")]
217 pub ask_size1: Option<f64>,
218
219 #[serde(rename = "ASKSIZE2")]
221 #[serde(with = "string_as_float_opt")]
222 #[serde(skip_serializing_if = "Option::is_none")]
223 pub ask_size2: Option<f64>,
224
225 #[serde(rename = "ASKSIZE3")]
227 #[serde(with = "string_as_float_opt")]
228 #[serde(skip_serializing_if = "Option::is_none")]
229 pub ask_size3: Option<f64>,
230
231 #[serde(rename = "ASKSIZE4")]
233 #[serde(with = "string_as_float_opt")]
234 #[serde(skip_serializing_if = "Option::is_none")]
235 pub ask_size4: Option<f64>,
236
237 #[serde(rename = "ASKSIZE5")]
239 #[serde(with = "string_as_float_opt")]
240 #[serde(skip_serializing_if = "Option::is_none")]
241 pub ask_size5: Option<f64>,
242
243 #[serde(rename = "CURRENCY0")]
245 #[serde(skip_serializing_if = "Option::is_none")]
246 pub currency0: Option<String>,
247
248 #[serde(rename = "CURRENCY1")]
250 #[serde(skip_serializing_if = "Option::is_none")]
251 pub currency1: Option<String>,
252
253 #[serde(rename = "CURRENCY2")]
255 #[serde(skip_serializing_if = "Option::is_none")]
256 pub currency2: Option<String>,
257
258 #[serde(rename = "CURRENCY3")]
260 #[serde(skip_serializing_if = "Option::is_none")]
261 pub currency3: Option<String>,
262
263 #[serde(rename = "CURRENCY4")]
265 #[serde(skip_serializing_if = "Option::is_none")]
266 pub currency4: Option<String>,
267
268 #[serde(rename = "CURRENCY5")]
270 #[serde(skip_serializing_if = "Option::is_none")]
271 pub currency5: Option<String>,
272
273 #[serde(rename = "C1BIDSIZE1")]
275 #[serde(with = "string_as_float_opt")]
276 #[serde(skip_serializing_if = "Option::is_none")]
277 pub c1_bid_size_1: Option<f64>,
278
279 #[serde(rename = "C1BIDSIZE2")]
281 #[serde(with = "string_as_float_opt")]
282 #[serde(skip_serializing_if = "Option::is_none")]
283 pub c1_bid_size_2: Option<f64>,
284
285 #[serde(rename = "C1BIDSIZE3")]
287 #[serde(with = "string_as_float_opt")]
288 #[serde(skip_serializing_if = "Option::is_none")]
289 pub c1_bid_size_3: Option<f64>,
290
291 #[serde(rename = "C1BIDSIZE4")]
293 #[serde(with = "string_as_float_opt")]
294 #[serde(skip_serializing_if = "Option::is_none")]
295 pub c1_bid_size_4: Option<f64>,
296
297 #[serde(rename = "C1BIDSIZE5")]
299 #[serde(with = "string_as_float_opt")]
300 #[serde(skip_serializing_if = "Option::is_none")]
301 pub c1_bid_size_5: Option<f64>,
302
303 #[serde(rename = "C2BIDSIZE1")]
305 #[serde(with = "string_as_float_opt")]
306 #[serde(skip_serializing_if = "Option::is_none")]
307 pub c2_bid_size_1: Option<f64>,
308
309 #[serde(rename = "C2BIDSIZE2")]
311 #[serde(with = "string_as_float_opt")]
312 #[serde(skip_serializing_if = "Option::is_none")]
313 pub c2_bid_size_2: Option<f64>,
314
315 #[serde(rename = "C2BIDSIZE3")]
317 #[serde(with = "string_as_float_opt")]
318 #[serde(skip_serializing_if = "Option::is_none")]
319 pub c2_bid_size_3: Option<f64>,
320
321 #[serde(rename = "C2BIDSIZE4")]
323 #[serde(with = "string_as_float_opt")]
324 #[serde(skip_serializing_if = "Option::is_none")]
325 pub c2_bid_size_4: Option<f64>,
326
327 #[serde(rename = "C2BIDSIZE5")]
329 #[serde(with = "string_as_float_opt")]
330 #[serde(skip_serializing_if = "Option::is_none")]
331 pub c2_bid_size_5: Option<f64>,
332
333 #[serde(rename = "C3BIDSIZE1")]
335 #[serde(with = "string_as_float_opt")]
336 #[serde(skip_serializing_if = "Option::is_none")]
337 pub c3_bid_size_1: Option<f64>,
338
339 #[serde(rename = "C3BIDSIZE2")]
341 #[serde(with = "string_as_float_opt")]
342 #[serde(skip_serializing_if = "Option::is_none")]
343 pub c3_bid_size_2: Option<f64>,
344
345 #[serde(rename = "C3BIDSIZE3")]
347 #[serde(with = "string_as_float_opt")]
348 #[serde(skip_serializing_if = "Option::is_none")]
349 pub c3_bid_size_3: Option<f64>,
350
351 #[serde(rename = "C3BIDSIZE4")]
353 #[serde(with = "string_as_float_opt")]
354 #[serde(skip_serializing_if = "Option::is_none")]
355 pub c3_bid_size_4: Option<f64>,
356
357 #[serde(rename = "C3BIDSIZE5")]
359 #[serde(with = "string_as_float_opt")]
360 #[serde(skip_serializing_if = "Option::is_none")]
361 pub c3_bid_size_5: Option<f64>,
362
363 #[serde(rename = "C4BIDSIZE1")]
365 #[serde(with = "string_as_float_opt")]
366 #[serde(skip_serializing_if = "Option::is_none")]
367 pub c4_bid_size_1: Option<f64>,
368
369 #[serde(rename = "C4BIDSIZE2")]
371 #[serde(with = "string_as_float_opt")]
372 #[serde(skip_serializing_if = "Option::is_none")]
373 pub c4_bid_size_2: Option<f64>,
374
375 #[serde(rename = "C4BIDSIZE3")]
377 #[serde(with = "string_as_float_opt")]
378 #[serde(skip_serializing_if = "Option::is_none")]
379 pub c4_bid_size_3: Option<f64>,
380
381 #[serde(rename = "C4BIDSIZE4")]
383 #[serde(with = "string_as_float_opt")]
384 #[serde(skip_serializing_if = "Option::is_none")]
385 pub c4_bid_size_4: Option<f64>,
386
387 #[serde(rename = "C4BIDSIZE5")]
389 #[serde(with = "string_as_float_opt")]
390 #[serde(skip_serializing_if = "Option::is_none")]
391 pub c4_bid_size_5: Option<f64>,
392
393 #[serde(rename = "C5BIDSIZE1")]
395 #[serde(with = "string_as_float_opt")]
396 #[serde(skip_serializing_if = "Option::is_none")]
397 pub c5_bid_size_1: Option<f64>,
398
399 #[serde(rename = "C5BIDSIZE2")]
401 #[serde(with = "string_as_float_opt")]
402 #[serde(skip_serializing_if = "Option::is_none")]
403 pub c5_bid_size_2: Option<f64>,
404
405 #[serde(rename = "C5BIDSIZE3")]
407 #[serde(with = "string_as_float_opt")]
408 #[serde(skip_serializing_if = "Option::is_none")]
409 pub c5_bid_size_3: Option<f64>,
410
411 #[serde(rename = "C5BIDSIZE4")]
413 #[serde(with = "string_as_float_opt")]
414 #[serde(skip_serializing_if = "Option::is_none")]
415 pub c5_bid_size_4: Option<f64>,
416
417 #[serde(rename = "C5BIDSIZE5")]
419 #[serde(with = "string_as_float_opt")]
420 #[serde(skip_serializing_if = "Option::is_none")]
421 pub c5_bid_size_5: Option<f64>,
422
423 #[serde(rename = "C1ASKSIZE1")]
426 #[serde(with = "string_as_float_opt")]
427 #[serde(skip_serializing_if = "Option::is_none")]
428 pub c1_ask_size_1: Option<f64>,
429
430 #[serde(rename = "C1ASKSIZE2")]
432 #[serde(with = "string_as_float_opt")]
433 #[serde(skip_serializing_if = "Option::is_none")]
434 pub c1_ask_size_2: Option<f64>,
435
436 #[serde(rename = "C1ASKSIZE3")]
438 #[serde(with = "string_as_float_opt")]
439 #[serde(skip_serializing_if = "Option::is_none")]
440 pub c1_ask_size_3: Option<f64>,
441
442 #[serde(rename = "C1ASKSIZE4")]
444 #[serde(with = "string_as_float_opt")]
445 #[serde(skip_serializing_if = "Option::is_none")]
446 pub c1_ask_size_4: Option<f64>,
447
448 #[serde(rename = "C1ASKSIZE5")]
450 #[serde(with = "string_as_float_opt")]
451 #[serde(skip_serializing_if = "Option::is_none")]
452 pub c1_ask_size_5: Option<f64>,
453
454 #[serde(rename = "C2ASKSIZE1")]
456 #[serde(with = "string_as_float_opt")]
457 #[serde(skip_serializing_if = "Option::is_none")]
458 pub c2_ask_size_1: Option<f64>,
459
460 #[serde(rename = "C2ASKSIZE2")]
462 #[serde(with = "string_as_float_opt")]
463 #[serde(skip_serializing_if = "Option::is_none")]
464 pub c2_ask_size_2: Option<f64>,
465
466 #[serde(rename = "C2ASKSIZE3")]
468 #[serde(with = "string_as_float_opt")]
469 #[serde(skip_serializing_if = "Option::is_none")]
470 pub c2_ask_size_3: Option<f64>,
471
472 #[serde(rename = "C2ASKSIZE4")]
474 #[serde(with = "string_as_float_opt")]
475 #[serde(skip_serializing_if = "Option::is_none")]
476 pub c2_ask_size_4: Option<f64>,
477
478 #[serde(rename = "C2ASKSIZE5")]
480 #[serde(with = "string_as_float_opt")]
481 #[serde(skip_serializing_if = "Option::is_none")]
482 pub c2_ask_size_5: Option<f64>,
483
484 #[serde(rename = "C3ASKSIZE1")]
486 #[serde(with = "string_as_float_opt")]
487 #[serde(skip_serializing_if = "Option::is_none")]
488 pub c3_ask_size_1: Option<f64>,
489
490 #[serde(rename = "C3ASKSIZE2")]
492 #[serde(with = "string_as_float_opt")]
493 #[serde(skip_serializing_if = "Option::is_none")]
494 pub c3_ask_size_2: Option<f64>,
495
496 #[serde(rename = "C3ASKSIZE3")]
498 #[serde(with = "string_as_float_opt")]
499 #[serde(skip_serializing_if = "Option::is_none")]
500 pub c3_ask_size_3: Option<f64>,
501
502 #[serde(rename = "C3ASKSIZE4")]
504 #[serde(with = "string_as_float_opt")]
505 #[serde(skip_serializing_if = "Option::is_none")]
506 pub c3_ask_size_4: Option<f64>,
507
508 #[serde(rename = "C3ASKSIZE5")]
510 #[serde(with = "string_as_float_opt")]
511 #[serde(skip_serializing_if = "Option::is_none")]
512 pub c3_ask_size_5: Option<f64>,
513
514 #[serde(rename = "C4ASKSIZE1")]
516 #[serde(with = "string_as_float_opt")]
517 #[serde(skip_serializing_if = "Option::is_none")]
518 pub c4_ask_size_1: Option<f64>,
519
520 #[serde(rename = "C4ASKSIZE2")]
522 #[serde(with = "string_as_float_opt")]
523 #[serde(skip_serializing_if = "Option::is_none")]
524 pub c4_ask_size_2: Option<f64>,
525
526 #[serde(rename = "C4ASKSIZE3")]
528 #[serde(with = "string_as_float_opt")]
529 #[serde(skip_serializing_if = "Option::is_none")]
530 pub c4_ask_size_3: Option<f64>,
531
532 #[serde(rename = "C4ASKSIZE4")]
534 #[serde(with = "string_as_float_opt")]
535 #[serde(skip_serializing_if = "Option::is_none")]
536 pub c4_ask_size_4: Option<f64>,
537
538 #[serde(rename = "C4ASKSIZE5")]
540 #[serde(with = "string_as_float_opt")]
541 #[serde(skip_serializing_if = "Option::is_none")]
542 pub c4_ask_size_5: Option<f64>,
543
544 #[serde(rename = "C5ASKSIZE1")]
546 #[serde(with = "string_as_float_opt")]
547 #[serde(skip_serializing_if = "Option::is_none")]
548 pub c5_ask_size_1: Option<f64>,
549
550 #[serde(rename = "C5ASKSIZE2")]
552 #[serde(with = "string_as_float_opt")]
553 #[serde(skip_serializing_if = "Option::is_none")]
554 pub c5_ask_size_2: Option<f64>,
555
556 #[serde(rename = "C5ASKSIZE3")]
558 #[serde(with = "string_as_float_opt")]
559 #[serde(skip_serializing_if = "Option::is_none")]
560 pub c5_ask_size_3: Option<f64>,
561
562 #[serde(rename = "C5ASKSIZE4")]
564 #[serde(with = "string_as_float_opt")]
565 #[serde(skip_serializing_if = "Option::is_none")]
566 pub c5_ask_size_4: Option<f64>,
567
568 #[serde(rename = "C5ASKSIZE5")]
570 #[serde(with = "string_as_float_opt")]
571 #[serde(skip_serializing_if = "Option::is_none")]
572 pub c5_ask_size_5: Option<f64>,
573
574 #[serde(rename = "TIMESTAMP")]
576 #[serde(with = "string_as_float_opt")]
577 #[serde(skip_serializing_if = "Option::is_none")]
578 pub timestamp: Option<f64>,
579
580 #[serde(rename = "DLG_FLAG")]
582 #[serde(skip_serializing_if = "Option::is_none")]
583 pub dealing_flag: Option<DealingFlag>,
584}
585
586impl PriceData {
587 pub fn from_item_update(item_update: &ItemUpdate) -> Result<Self, String> {
597 let item_name = item_update.item_name.clone().unwrap_or_default();
599
600 let item_pos = item_update.item_pos as i32;
602
603 let is_snapshot = item_update.is_snapshot;
605
606 let fields = Self::create_price_fields(&item_update.fields)?;
608
609 let mut changed_fields_map: HashMap<String, Option<String>> = HashMap::new();
611 for (key, value) in &item_update.changed_fields {
612 changed_fields_map.insert(key.clone(), Some(value.clone()));
613 }
614 let changed_fields = Self::create_price_fields(&changed_fields_map)?;
615
616 Ok(PriceData {
617 item_name,
618 item_pos,
619 fields,
620 changed_fields,
621 is_snapshot,
622 })
623 }
624
625 fn create_price_fields(
627 fields_map: &HashMap<String, Option<String>>,
628 ) -> Result<PriceFields, String> {
629 let get_field = |key: &str| -> Option<String> { fields_map.get(key).cloned().flatten() };
631
632 let parse_float = |key: &str| -> Result<Option<f64>, String> {
634 match get_field(key) {
635 Some(val) if !val.is_empty() => val
636 .parse::<f64>()
637 .map(Some)
638 .map_err(|_| format!("Failed to parse {key} as float: {val}")),
639 _ => Ok(None),
640 }
641 };
642
643 let dealing_flag = match get_field("DLG_FLAG").as_deref() {
645 Some("CLOSED") => Some(DealingFlag::Closed),
646 Some("CALL") => Some(DealingFlag::Call),
647 Some("DEAL") => Some(DealingFlag::Deal),
648 Some("EDIT") => Some(DealingFlag::Edit),
649 Some("CLOSINGONLY") => Some(DealingFlag::ClosingOnly),
650 Some("DEALNOEDIT") => Some(DealingFlag::DealNoEdit),
651 Some("AUCTION") => Some(DealingFlag::Auction),
652 Some("AUCTIONNOEDIT") => Some(DealingFlag::AuctionNoEdit),
653 Some("SUSPEND") => Some(DealingFlag::Suspend),
654 Some(unknown) => return Err(format!("Unknown dealing flag: {unknown}")),
655 None => None,
656 };
657
658 Ok(PriceFields {
659 mid_open: parse_float("MID_OPEN")?,
660 high: parse_float("HIGH")?,
661 low: parse_float("LOW")?,
662 bid: parse_float("BID")?,
663 offer: parse_float("OFFER")?,
664 change: parse_float("CHANGE")?,
665 change_pct: parse_float("CHANGE_PCT")?,
666 market_delay: parse_float("MARKET_DELAY")?,
667 market_state: get_field("MARKET_STATE"),
668 update_time: get_field("UPDATE_TIME"),
669
670 bid_quote_id: get_field("BIDQUOTEID"),
671 ask_quote_id: get_field("ASKQUOTEID"),
672
673 bid_price1: parse_float("BIDPRICE1")?,
675 bid_price2: parse_float("BIDPRICE2")?,
676 bid_price3: parse_float("BIDPRICE3")?,
677 bid_price4: parse_float("BIDPRICE4")?,
678 bid_price5: parse_float("BIDPRICE5")?,
679
680 ask_price1: parse_float("ASKPRICE1")?,
682 ask_price2: parse_float("ASKPRICE2")?,
683 ask_price3: parse_float("ASKPRICE3")?,
684 ask_price4: parse_float("ASKPRICE4")?,
685 ask_price5: parse_float("ASKPRICE5")?,
686
687 bid_size1: parse_float("BIDSIZE1")?,
689 bid_size2: parse_float("BIDSIZE2")?,
690 bid_size3: parse_float("BIDSIZE3")?,
691 bid_size4: parse_float("BIDSIZE4")?,
692 bid_size5: parse_float("BIDSIZE5")?,
693
694 ask_size1: parse_float("ASKSIZE1")?,
696 ask_size2: parse_float("ASKSIZE2")?,
697 ask_size3: parse_float("ASKSIZE3")?,
698 ask_size4: parse_float("ASKSIZE4")?,
699 ask_size5: parse_float("ASKSIZE5")?,
700
701 currency0: get_field("CURRENCY0"),
703 currency1: get_field("CURRENCY1"),
704 currency2: get_field("CURRENCY2"),
705 currency3: get_field("CURRENCY3"),
706 currency4: get_field("CURRENCY4"),
707 currency5: get_field("CURRENCY5"),
708
709 c1_bid_size_1: parse_float("C1BIDSIZE1")?,
711 c1_bid_size_2: parse_float("C1BIDSIZE2")?,
712 c1_bid_size_3: parse_float("C1BIDSIZE3")?,
713 c1_bid_size_4: parse_float("C1BIDSIZE4")?,
714 c1_bid_size_5: parse_float("C1BIDSIZE5")?,
715
716 c2_bid_size_1: parse_float("C2BIDSIZE1")?,
717 c2_bid_size_2: parse_float("C2BIDSIZE2")?,
718 c2_bid_size_3: parse_float("C2BIDSIZE3")?,
719 c2_bid_size_4: parse_float("C2BIDSIZE4")?,
720 c2_bid_size_5: parse_float("C2BIDSIZE5")?,
721
722 c3_bid_size_1: parse_float("C3BIDSIZE1")?,
723 c3_bid_size_2: parse_float("C3BIDSIZE2")?,
724 c3_bid_size_3: parse_float("C3BIDSIZE3")?,
725 c3_bid_size_4: parse_float("C3BIDSIZE4")?,
726 c3_bid_size_5: parse_float("C3BIDSIZE5")?,
727
728 c4_bid_size_1: parse_float("C4BIDSIZE1")?,
729 c4_bid_size_2: parse_float("C4BIDSIZE2")?,
730 c4_bid_size_3: parse_float("C4BIDSIZE3")?,
731 c4_bid_size_4: parse_float("C4BIDSIZE4")?,
732 c4_bid_size_5: parse_float("C4BIDSIZE5")?,
733
734 c5_bid_size_1: parse_float("C5BIDSIZE1")?,
735 c5_bid_size_2: parse_float("C5BIDSIZE2")?,
736 c5_bid_size_3: parse_float("C5BIDSIZE3")?,
737 c5_bid_size_4: parse_float("C5BIDSIZE4")?,
738 c5_bid_size_5: parse_float("C5BIDSIZE5")?,
739
740 c1_ask_size_1: parse_float("C1ASKSIZE1")?,
742 c1_ask_size_2: parse_float("C1ASKSIZE2")?,
743 c1_ask_size_3: parse_float("C1ASKSIZE3")?,
744 c1_ask_size_4: parse_float("C1ASKSIZE4")?,
745 c1_ask_size_5: parse_float("C1ASKSIZE5")?,
746
747 c2_ask_size_1: parse_float("C2ASKSIZE1")?,
748 c2_ask_size_2: parse_float("C2ASKSIZE2")?,
749 c2_ask_size_3: parse_float("C2ASKSIZE3")?,
750 c2_ask_size_4: parse_float("C2ASKSIZE4")?,
751 c2_ask_size_5: parse_float("C2ASKSIZE5")?,
752
753 c3_ask_size_1: parse_float("C3ASKSIZE1")?,
754 c3_ask_size_2: parse_float("C3ASKSIZE2")?,
755 c3_ask_size_3: parse_float("C3ASKSIZE3")?,
756 c3_ask_size_4: parse_float("C3ASKSIZE4")?,
757 c3_ask_size_5: parse_float("C3ASKSIZE5")?,
758
759 c4_ask_size_1: parse_float("C4ASKSIZE1")?,
760 c4_ask_size_2: parse_float("C4ASKSIZE2")?,
761 c4_ask_size_3: parse_float("C4ASKSIZE3")?,
762 c4_ask_size_4: parse_float("C4ASKSIZE4")?,
763 c4_ask_size_5: parse_float("C4ASKSIZE5")?,
764
765 c5_ask_size_1: parse_float("C5ASKSIZE1")?,
766 c5_ask_size_2: parse_float("C5ASKSIZE2")?,
767 c5_ask_size_3: parse_float("C5ASKSIZE3")?,
768 c5_ask_size_4: parse_float("C5ASKSIZE4")?,
769 c5_ask_size_5: parse_float("C5ASKSIZE5")?,
770
771 timestamp: parse_float("TIMESTAMP")?,
772 dealing_flag,
773 })
774 }
775}
776
777impl From<&ItemUpdate> for PriceData {
778 fn from(item_update: &ItemUpdate) -> Self {
779 PriceData::from_item_update(item_update).unwrap_or_default()
780 }
781}