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#[repr(u8)]
9#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, Default)]
10#[serde(rename_all = "UPPERCASE")]
11pub enum DealingFlag {
12 #[default]
14 Closed,
15 Call,
17 Deal,
19 Edit,
21 ClosingOnly,
23 DealNoEdit,
25 Auction,
27 AuctionNoEdit,
29 Suspend,
31}
32
33#[derive(DebugPretty, Clone, DisplaySimple, Serialize, Deserialize, Default)]
36pub struct PriceData {
37 pub item_name: String,
39 pub item_pos: i32,
41 pub fields: PriceFields,
43 pub changed_fields: PriceFields,
45 pub is_snapshot: bool,
47}
48
49#[derive(DebugPretty, DisplaySimple, Clone, Serialize, Deserialize, Default)]
51pub struct PriceFields {
52 #[serde(rename = "MID_OPEN")]
54 #[serde(with = "string_as_float_opt")]
55 #[serde(skip_serializing_if = "Option::is_none")]
56 pub mid_open: Option<f64>,
57
58 #[serde(rename = "HIGH")]
60 #[serde(with = "string_as_float_opt")]
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub high: Option<f64>,
63
64 #[serde(rename = "LOW")]
66 #[serde(with = "string_as_float_opt")]
67 #[serde(skip_serializing_if = "Option::is_none")]
68 pub low: Option<f64>,
69
70 #[serde(rename = "BID")]
72 #[serde(with = "string_as_float_opt")]
73 #[serde(skip_serializing_if = "Option::is_none")]
74 pub bid: Option<f64>,
75
76 #[serde(rename = "OFFER")]
78 #[serde(with = "string_as_float_opt")]
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub offer: Option<f64>,
81
82 #[serde(rename = "CHANGE")]
84 #[serde(with = "string_as_float_opt")]
85 #[serde(skip_serializing_if = "Option::is_none")]
86 pub change: Option<f64>,
87
88 #[serde(rename = "CHANGE_PCT")]
90 #[serde(with = "string_as_float_opt")]
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub change_pct: Option<f64>,
93
94 #[serde(rename = "MARKET_DELAY")]
96 #[serde(with = "string_as_float_opt")]
97 #[serde(skip_serializing_if = "Option::is_none")]
98 pub market_delay: Option<f64>,
99
100 #[serde(rename = "MARKET_STATE")]
102 #[serde(skip_serializing_if = "Option::is_none")]
103 pub market_state: Option<String>,
104
105 #[serde(rename = "UPDATE_TIME")]
107 #[serde(skip_serializing_if = "Option::is_none")]
108 pub update_time: Option<String>,
109
110 #[serde(rename = "BIDQUOTEID")]
112 #[serde(skip_serializing_if = "Option::is_none")]
113 pub bid_quote_id: Option<String>,
114
115 #[serde(rename = "ASKQUOTEID")]
117 #[serde(skip_serializing_if = "Option::is_none")]
118 pub ask_quote_id: Option<String>,
119
120 #[serde(rename = "BIDPRICE1")]
123 #[serde(with = "string_as_float_opt")]
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub bid_price1: Option<f64>,
126
127 #[serde(rename = "BIDPRICE2")]
129 #[serde(with = "string_as_float_opt")]
130 #[serde(skip_serializing_if = "Option::is_none")]
131 pub bid_price2: Option<f64>,
132
133 #[serde(rename = "BIDPRICE3")]
135 #[serde(with = "string_as_float_opt")]
136 #[serde(skip_serializing_if = "Option::is_none")]
137 pub bid_price3: Option<f64>,
138
139 #[serde(rename = "BIDPRICE4")]
141 #[serde(with = "string_as_float_opt")]
142 #[serde(skip_serializing_if = "Option::is_none")]
143 pub bid_price4: Option<f64>,
144
145 #[serde(rename = "BIDPRICE5")]
147 #[serde(with = "string_as_float_opt")]
148 #[serde(skip_serializing_if = "Option::is_none")]
149 pub bid_price5: Option<f64>,
150
151 #[serde(rename = "ASKPRICE1")]
154 #[serde(with = "string_as_float_opt")]
155 #[serde(skip_serializing_if = "Option::is_none")]
156 pub ask_price1: Option<f64>,
157
158 #[serde(rename = "ASKPRICE2")]
160 #[serde(with = "string_as_float_opt")]
161 #[serde(skip_serializing_if = "Option::is_none")]
162 pub ask_price2: Option<f64>,
163
164 #[serde(rename = "ASKPRICE3")]
166 #[serde(with = "string_as_float_opt")]
167 #[serde(skip_serializing_if = "Option::is_none")]
168 pub ask_price3: Option<f64>,
169
170 #[serde(rename = "ASKPRICE4")]
172 #[serde(with = "string_as_float_opt")]
173 #[serde(skip_serializing_if = "Option::is_none")]
174 pub ask_price4: Option<f64>,
175
176 #[serde(rename = "ASKPRICE5")]
178 #[serde(with = "string_as_float_opt")]
179 #[serde(skip_serializing_if = "Option::is_none")]
180 pub ask_price5: Option<f64>,
181
182 #[serde(rename = "BIDSIZE1")]
185 #[serde(with = "string_as_float_opt")]
186 #[serde(skip_serializing_if = "Option::is_none")]
187 pub bid_size1: Option<f64>,
188
189 #[serde(rename = "BIDSIZE2")]
191 #[serde(with = "string_as_float_opt")]
192 #[serde(skip_serializing_if = "Option::is_none")]
193 pub bid_size2: Option<f64>,
194
195 #[serde(rename = "BIDSIZE3")]
197 #[serde(with = "string_as_float_opt")]
198 #[serde(skip_serializing_if = "Option::is_none")]
199 pub bid_size3: Option<f64>,
200
201 #[serde(rename = "BIDSIZE4")]
203 #[serde(with = "string_as_float_opt")]
204 #[serde(skip_serializing_if = "Option::is_none")]
205 pub bid_size4: Option<f64>,
206
207 #[serde(rename = "BIDSIZE5")]
209 #[serde(with = "string_as_float_opt")]
210 #[serde(skip_serializing_if = "Option::is_none")]
211 pub bid_size5: Option<f64>,
212
213 #[serde(rename = "ASKSIZE1")]
216 #[serde(with = "string_as_float_opt")]
217 #[serde(skip_serializing_if = "Option::is_none")]
218 pub ask_size1: Option<f64>,
219
220 #[serde(rename = "ASKSIZE2")]
222 #[serde(with = "string_as_float_opt")]
223 #[serde(skip_serializing_if = "Option::is_none")]
224 pub ask_size2: Option<f64>,
225
226 #[serde(rename = "ASKSIZE3")]
228 #[serde(with = "string_as_float_opt")]
229 #[serde(skip_serializing_if = "Option::is_none")]
230 pub ask_size3: Option<f64>,
231
232 #[serde(rename = "ASKSIZE4")]
234 #[serde(with = "string_as_float_opt")]
235 #[serde(skip_serializing_if = "Option::is_none")]
236 pub ask_size4: Option<f64>,
237
238 #[serde(rename = "ASKSIZE5")]
240 #[serde(with = "string_as_float_opt")]
241 #[serde(skip_serializing_if = "Option::is_none")]
242 pub ask_size5: Option<f64>,
243
244 #[serde(rename = "CURRENCY0")]
246 #[serde(skip_serializing_if = "Option::is_none")]
247 pub currency0: Option<String>,
248
249 #[serde(rename = "CURRENCY1")]
251 #[serde(skip_serializing_if = "Option::is_none")]
252 pub currency1: Option<String>,
253
254 #[serde(rename = "CURRENCY2")]
256 #[serde(skip_serializing_if = "Option::is_none")]
257 pub currency2: Option<String>,
258
259 #[serde(rename = "CURRENCY3")]
261 #[serde(skip_serializing_if = "Option::is_none")]
262 pub currency3: Option<String>,
263
264 #[serde(rename = "CURRENCY4")]
266 #[serde(skip_serializing_if = "Option::is_none")]
267 pub currency4: Option<String>,
268
269 #[serde(rename = "CURRENCY5")]
271 #[serde(skip_serializing_if = "Option::is_none")]
272 pub currency5: Option<String>,
273
274 #[serde(rename = "C1BIDSIZE1")]
276 #[serde(with = "string_as_float_opt")]
277 #[serde(skip_serializing_if = "Option::is_none")]
278 pub c1_bid_size_1: Option<f64>,
279
280 #[serde(rename = "C1BIDSIZE2")]
282 #[serde(with = "string_as_float_opt")]
283 #[serde(skip_serializing_if = "Option::is_none")]
284 pub c1_bid_size_2: Option<f64>,
285
286 #[serde(rename = "C1BIDSIZE3")]
288 #[serde(with = "string_as_float_opt")]
289 #[serde(skip_serializing_if = "Option::is_none")]
290 pub c1_bid_size_3: Option<f64>,
291
292 #[serde(rename = "C1BIDSIZE4")]
294 #[serde(with = "string_as_float_opt")]
295 #[serde(skip_serializing_if = "Option::is_none")]
296 pub c1_bid_size_4: Option<f64>,
297
298 #[serde(rename = "C1BIDSIZE5")]
300 #[serde(with = "string_as_float_opt")]
301 #[serde(skip_serializing_if = "Option::is_none")]
302 pub c1_bid_size_5: Option<f64>,
303
304 #[serde(rename = "C2BIDSIZE1")]
306 #[serde(with = "string_as_float_opt")]
307 #[serde(skip_serializing_if = "Option::is_none")]
308 pub c2_bid_size_1: Option<f64>,
309
310 #[serde(rename = "C2BIDSIZE2")]
312 #[serde(with = "string_as_float_opt")]
313 #[serde(skip_serializing_if = "Option::is_none")]
314 pub c2_bid_size_2: Option<f64>,
315
316 #[serde(rename = "C2BIDSIZE3")]
318 #[serde(with = "string_as_float_opt")]
319 #[serde(skip_serializing_if = "Option::is_none")]
320 pub c2_bid_size_3: Option<f64>,
321
322 #[serde(rename = "C2BIDSIZE4")]
324 #[serde(with = "string_as_float_opt")]
325 #[serde(skip_serializing_if = "Option::is_none")]
326 pub c2_bid_size_4: Option<f64>,
327
328 #[serde(rename = "C2BIDSIZE5")]
330 #[serde(with = "string_as_float_opt")]
331 #[serde(skip_serializing_if = "Option::is_none")]
332 pub c2_bid_size_5: Option<f64>,
333
334 #[serde(rename = "C3BIDSIZE1")]
336 #[serde(with = "string_as_float_opt")]
337 #[serde(skip_serializing_if = "Option::is_none")]
338 pub c3_bid_size_1: Option<f64>,
339
340 #[serde(rename = "C3BIDSIZE2")]
342 #[serde(with = "string_as_float_opt")]
343 #[serde(skip_serializing_if = "Option::is_none")]
344 pub c3_bid_size_2: Option<f64>,
345
346 #[serde(rename = "C3BIDSIZE3")]
348 #[serde(with = "string_as_float_opt")]
349 #[serde(skip_serializing_if = "Option::is_none")]
350 pub c3_bid_size_3: Option<f64>,
351
352 #[serde(rename = "C3BIDSIZE4")]
354 #[serde(with = "string_as_float_opt")]
355 #[serde(skip_serializing_if = "Option::is_none")]
356 pub c3_bid_size_4: Option<f64>,
357
358 #[serde(rename = "C3BIDSIZE5")]
360 #[serde(with = "string_as_float_opt")]
361 #[serde(skip_serializing_if = "Option::is_none")]
362 pub c3_bid_size_5: Option<f64>,
363
364 #[serde(rename = "C4BIDSIZE1")]
366 #[serde(with = "string_as_float_opt")]
367 #[serde(skip_serializing_if = "Option::is_none")]
368 pub c4_bid_size_1: Option<f64>,
369
370 #[serde(rename = "C4BIDSIZE2")]
372 #[serde(with = "string_as_float_opt")]
373 #[serde(skip_serializing_if = "Option::is_none")]
374 pub c4_bid_size_2: Option<f64>,
375
376 #[serde(rename = "C4BIDSIZE3")]
378 #[serde(with = "string_as_float_opt")]
379 #[serde(skip_serializing_if = "Option::is_none")]
380 pub c4_bid_size_3: Option<f64>,
381
382 #[serde(rename = "C4BIDSIZE4")]
384 #[serde(with = "string_as_float_opt")]
385 #[serde(skip_serializing_if = "Option::is_none")]
386 pub c4_bid_size_4: Option<f64>,
387
388 #[serde(rename = "C4BIDSIZE5")]
390 #[serde(with = "string_as_float_opt")]
391 #[serde(skip_serializing_if = "Option::is_none")]
392 pub c4_bid_size_5: Option<f64>,
393
394 #[serde(rename = "C5BIDSIZE1")]
396 #[serde(with = "string_as_float_opt")]
397 #[serde(skip_serializing_if = "Option::is_none")]
398 pub c5_bid_size_1: Option<f64>,
399
400 #[serde(rename = "C5BIDSIZE2")]
402 #[serde(with = "string_as_float_opt")]
403 #[serde(skip_serializing_if = "Option::is_none")]
404 pub c5_bid_size_2: Option<f64>,
405
406 #[serde(rename = "C5BIDSIZE3")]
408 #[serde(with = "string_as_float_opt")]
409 #[serde(skip_serializing_if = "Option::is_none")]
410 pub c5_bid_size_3: Option<f64>,
411
412 #[serde(rename = "C5BIDSIZE4")]
414 #[serde(with = "string_as_float_opt")]
415 #[serde(skip_serializing_if = "Option::is_none")]
416 pub c5_bid_size_4: Option<f64>,
417
418 #[serde(rename = "C5BIDSIZE5")]
420 #[serde(with = "string_as_float_opt")]
421 #[serde(skip_serializing_if = "Option::is_none")]
422 pub c5_bid_size_5: Option<f64>,
423
424 #[serde(rename = "C1ASKSIZE1")]
427 #[serde(with = "string_as_float_opt")]
428 #[serde(skip_serializing_if = "Option::is_none")]
429 pub c1_ask_size_1: Option<f64>,
430
431 #[serde(rename = "C1ASKSIZE2")]
433 #[serde(with = "string_as_float_opt")]
434 #[serde(skip_serializing_if = "Option::is_none")]
435 pub c1_ask_size_2: Option<f64>,
436
437 #[serde(rename = "C1ASKSIZE3")]
439 #[serde(with = "string_as_float_opt")]
440 #[serde(skip_serializing_if = "Option::is_none")]
441 pub c1_ask_size_3: Option<f64>,
442
443 #[serde(rename = "C1ASKSIZE4")]
445 #[serde(with = "string_as_float_opt")]
446 #[serde(skip_serializing_if = "Option::is_none")]
447 pub c1_ask_size_4: Option<f64>,
448
449 #[serde(rename = "C1ASKSIZE5")]
451 #[serde(with = "string_as_float_opt")]
452 #[serde(skip_serializing_if = "Option::is_none")]
453 pub c1_ask_size_5: Option<f64>,
454
455 #[serde(rename = "C2ASKSIZE1")]
457 #[serde(with = "string_as_float_opt")]
458 #[serde(skip_serializing_if = "Option::is_none")]
459 pub c2_ask_size_1: Option<f64>,
460
461 #[serde(rename = "C2ASKSIZE2")]
463 #[serde(with = "string_as_float_opt")]
464 #[serde(skip_serializing_if = "Option::is_none")]
465 pub c2_ask_size_2: Option<f64>,
466
467 #[serde(rename = "C2ASKSIZE3")]
469 #[serde(with = "string_as_float_opt")]
470 #[serde(skip_serializing_if = "Option::is_none")]
471 pub c2_ask_size_3: Option<f64>,
472
473 #[serde(rename = "C2ASKSIZE4")]
475 #[serde(with = "string_as_float_opt")]
476 #[serde(skip_serializing_if = "Option::is_none")]
477 pub c2_ask_size_4: Option<f64>,
478
479 #[serde(rename = "C2ASKSIZE5")]
481 #[serde(with = "string_as_float_opt")]
482 #[serde(skip_serializing_if = "Option::is_none")]
483 pub c2_ask_size_5: Option<f64>,
484
485 #[serde(rename = "C3ASKSIZE1")]
487 #[serde(with = "string_as_float_opt")]
488 #[serde(skip_serializing_if = "Option::is_none")]
489 pub c3_ask_size_1: Option<f64>,
490
491 #[serde(rename = "C3ASKSIZE2")]
493 #[serde(with = "string_as_float_opt")]
494 #[serde(skip_serializing_if = "Option::is_none")]
495 pub c3_ask_size_2: Option<f64>,
496
497 #[serde(rename = "C3ASKSIZE3")]
499 #[serde(with = "string_as_float_opt")]
500 #[serde(skip_serializing_if = "Option::is_none")]
501 pub c3_ask_size_3: Option<f64>,
502
503 #[serde(rename = "C3ASKSIZE4")]
505 #[serde(with = "string_as_float_opt")]
506 #[serde(skip_serializing_if = "Option::is_none")]
507 pub c3_ask_size_4: Option<f64>,
508
509 #[serde(rename = "C3ASKSIZE5")]
511 #[serde(with = "string_as_float_opt")]
512 #[serde(skip_serializing_if = "Option::is_none")]
513 pub c3_ask_size_5: Option<f64>,
514
515 #[serde(rename = "C4ASKSIZE1")]
517 #[serde(with = "string_as_float_opt")]
518 #[serde(skip_serializing_if = "Option::is_none")]
519 pub c4_ask_size_1: Option<f64>,
520
521 #[serde(rename = "C4ASKSIZE2")]
523 #[serde(with = "string_as_float_opt")]
524 #[serde(skip_serializing_if = "Option::is_none")]
525 pub c4_ask_size_2: Option<f64>,
526
527 #[serde(rename = "C4ASKSIZE3")]
529 #[serde(with = "string_as_float_opt")]
530 #[serde(skip_serializing_if = "Option::is_none")]
531 pub c4_ask_size_3: Option<f64>,
532
533 #[serde(rename = "C4ASKSIZE4")]
535 #[serde(with = "string_as_float_opt")]
536 #[serde(skip_serializing_if = "Option::is_none")]
537 pub c4_ask_size_4: Option<f64>,
538
539 #[serde(rename = "C4ASKSIZE5")]
541 #[serde(with = "string_as_float_opt")]
542 #[serde(skip_serializing_if = "Option::is_none")]
543 pub c4_ask_size_5: Option<f64>,
544
545 #[serde(rename = "C5ASKSIZE1")]
547 #[serde(with = "string_as_float_opt")]
548 #[serde(skip_serializing_if = "Option::is_none")]
549 pub c5_ask_size_1: Option<f64>,
550
551 #[serde(rename = "C5ASKSIZE2")]
553 #[serde(with = "string_as_float_opt")]
554 #[serde(skip_serializing_if = "Option::is_none")]
555 pub c5_ask_size_2: Option<f64>,
556
557 #[serde(rename = "C5ASKSIZE3")]
559 #[serde(with = "string_as_float_opt")]
560 #[serde(skip_serializing_if = "Option::is_none")]
561 pub c5_ask_size_3: Option<f64>,
562
563 #[serde(rename = "C5ASKSIZE4")]
565 #[serde(with = "string_as_float_opt")]
566 #[serde(skip_serializing_if = "Option::is_none")]
567 pub c5_ask_size_4: Option<f64>,
568
569 #[serde(rename = "C5ASKSIZE5")]
571 #[serde(with = "string_as_float_opt")]
572 #[serde(skip_serializing_if = "Option::is_none")]
573 pub c5_ask_size_5: Option<f64>,
574
575 #[serde(rename = "TIMESTAMP")]
577 #[serde(with = "string_as_float_opt")]
578 #[serde(skip_serializing_if = "Option::is_none")]
579 pub timestamp: Option<f64>,
580
581 #[serde(rename = "DLG_FLAG")]
583 #[serde(skip_serializing_if = "Option::is_none")]
584 pub dealing_flag: Option<DealingFlag>,
585}
586
587impl PriceData {
588 pub fn from_item_update(item_update: &ItemUpdate) -> Result<Self, String> {
598 let item_name = item_update.item_name.clone().unwrap_or_default();
600
601 let item_pos = item_update.item_pos as i32;
603
604 let is_snapshot = item_update.is_snapshot;
606
607 let fields = Self::create_price_fields(&item_update.fields)?;
609
610 let mut changed_fields_map: HashMap<String, Option<String>> = HashMap::new();
612 for (key, value) in &item_update.changed_fields {
613 changed_fields_map.insert(key.clone(), Some(value.clone()));
614 }
615 let changed_fields = Self::create_price_fields(&changed_fields_map)?;
616
617 Ok(PriceData {
618 item_name,
619 item_pos,
620 fields,
621 changed_fields,
622 is_snapshot,
623 })
624 }
625
626 fn create_price_fields(
628 fields_map: &HashMap<String, Option<String>>,
629 ) -> Result<PriceFields, String> {
630 let get_field = |key: &str| -> Option<String> { fields_map.get(key).cloned().flatten() };
632
633 let parse_float = |key: &str| -> Result<Option<f64>, String> {
635 match get_field(key) {
636 Some(val) if !val.is_empty() => val
637 .parse::<f64>()
638 .map(Some)
639 .map_err(|_| format!("Failed to parse {key} as float: {val}")),
640 _ => Ok(None),
641 }
642 };
643
644 let dealing_flag = match get_field("DLG_FLAG")
646 .as_deref()
647 .map(|s| s.to_uppercase())
648 .as_deref()
649 {
650 Some("CLOSED") => Some(DealingFlag::Closed),
651 Some("CALL") => Some(DealingFlag::Call),
652 Some("DEAL") => Some(DealingFlag::Deal),
653 Some("EDIT") => Some(DealingFlag::Edit),
654 Some("CLOSINGONLY") => Some(DealingFlag::ClosingOnly),
655 Some("DEALNOEDIT") => Some(DealingFlag::DealNoEdit),
656 Some("AUCTION") => Some(DealingFlag::Auction),
657 Some("AUCTIONNOEDIT") => Some(DealingFlag::AuctionNoEdit),
658 Some("SUSPEND") => Some(DealingFlag::Suspend),
659 Some(unknown) => return Err(format!("Unknown dealing flag: {unknown}")),
660 None => None,
661 };
662
663 Ok(PriceFields {
664 mid_open: parse_float("MID_OPEN")?,
665 high: parse_float("HIGH")?,
666 low: parse_float("LOW")?,
667 bid: parse_float("BID")?,
668 offer: parse_float("OFFER")?,
669 change: parse_float("CHANGE")?,
670 change_pct: parse_float("CHANGE_PCT")?,
671 market_delay: parse_float("MARKET_DELAY")?,
672 market_state: get_field("MARKET_STATE"),
673 update_time: get_field("UPDATE_TIME"),
674
675 bid_quote_id: get_field("BIDQUOTEID"),
676 ask_quote_id: get_field("ASKQUOTEID"),
677
678 bid_price1: parse_float("BIDPRICE1")?,
680 bid_price2: parse_float("BIDPRICE2")?,
681 bid_price3: parse_float("BIDPRICE3")?,
682 bid_price4: parse_float("BIDPRICE4")?,
683 bid_price5: parse_float("BIDPRICE5")?,
684
685 ask_price1: parse_float("ASKPRICE1")?,
687 ask_price2: parse_float("ASKPRICE2")?,
688 ask_price3: parse_float("ASKPRICE3")?,
689 ask_price4: parse_float("ASKPRICE4")?,
690 ask_price5: parse_float("ASKPRICE5")?,
691
692 bid_size1: parse_float("BIDSIZE1")?,
694 bid_size2: parse_float("BIDSIZE2")?,
695 bid_size3: parse_float("BIDSIZE3")?,
696 bid_size4: parse_float("BIDSIZE4")?,
697 bid_size5: parse_float("BIDSIZE5")?,
698
699 ask_size1: parse_float("ASKSIZE1")?,
701 ask_size2: parse_float("ASKSIZE2")?,
702 ask_size3: parse_float("ASKSIZE3")?,
703 ask_size4: parse_float("ASKSIZE4")?,
704 ask_size5: parse_float("ASKSIZE5")?,
705
706 currency0: get_field("CURRENCY0"),
708 currency1: get_field("CURRENCY1"),
709 currency2: get_field("CURRENCY2"),
710 currency3: get_field("CURRENCY3"),
711 currency4: get_field("CURRENCY4"),
712 currency5: get_field("CURRENCY5"),
713
714 c1_bid_size_1: parse_float("C1BIDSIZE1")?,
716 c1_bid_size_2: parse_float("C1BIDSIZE2")?,
717 c1_bid_size_3: parse_float("C1BIDSIZE3")?,
718 c1_bid_size_4: parse_float("C1BIDSIZE4")?,
719 c1_bid_size_5: parse_float("C1BIDSIZE5")?,
720
721 c2_bid_size_1: parse_float("C2BIDSIZE1")?,
722 c2_bid_size_2: parse_float("C2BIDSIZE2")?,
723 c2_bid_size_3: parse_float("C2BIDSIZE3")?,
724 c2_bid_size_4: parse_float("C2BIDSIZE4")?,
725 c2_bid_size_5: parse_float("C2BIDSIZE5")?,
726
727 c3_bid_size_1: parse_float("C3BIDSIZE1")?,
728 c3_bid_size_2: parse_float("C3BIDSIZE2")?,
729 c3_bid_size_3: parse_float("C3BIDSIZE3")?,
730 c3_bid_size_4: parse_float("C3BIDSIZE4")?,
731 c3_bid_size_5: parse_float("C3BIDSIZE5")?,
732
733 c4_bid_size_1: parse_float("C4BIDSIZE1")?,
734 c4_bid_size_2: parse_float("C4BIDSIZE2")?,
735 c4_bid_size_3: parse_float("C4BIDSIZE3")?,
736 c4_bid_size_4: parse_float("C4BIDSIZE4")?,
737 c4_bid_size_5: parse_float("C4BIDSIZE5")?,
738
739 c5_bid_size_1: parse_float("C5BIDSIZE1")?,
740 c5_bid_size_2: parse_float("C5BIDSIZE2")?,
741 c5_bid_size_3: parse_float("C5BIDSIZE3")?,
742 c5_bid_size_4: parse_float("C5BIDSIZE4")?,
743 c5_bid_size_5: parse_float("C5BIDSIZE5")?,
744
745 c1_ask_size_1: parse_float("C1ASKSIZE1")?,
747 c1_ask_size_2: parse_float("C1ASKSIZE2")?,
748 c1_ask_size_3: parse_float("C1ASKSIZE3")?,
749 c1_ask_size_4: parse_float("C1ASKSIZE4")?,
750 c1_ask_size_5: parse_float("C1ASKSIZE5")?,
751
752 c2_ask_size_1: parse_float("C2ASKSIZE1")?,
753 c2_ask_size_2: parse_float("C2ASKSIZE2")?,
754 c2_ask_size_3: parse_float("C2ASKSIZE3")?,
755 c2_ask_size_4: parse_float("C2ASKSIZE4")?,
756 c2_ask_size_5: parse_float("C2ASKSIZE5")?,
757
758 c3_ask_size_1: parse_float("C3ASKSIZE1")?,
759 c3_ask_size_2: parse_float("C3ASKSIZE2")?,
760 c3_ask_size_3: parse_float("C3ASKSIZE3")?,
761 c3_ask_size_4: parse_float("C3ASKSIZE4")?,
762 c3_ask_size_5: parse_float("C3ASKSIZE5")?,
763
764 c4_ask_size_1: parse_float("C4ASKSIZE1")?,
765 c4_ask_size_2: parse_float("C4ASKSIZE2")?,
766 c4_ask_size_3: parse_float("C4ASKSIZE3")?,
767 c4_ask_size_4: parse_float("C4ASKSIZE4")?,
768 c4_ask_size_5: parse_float("C4ASKSIZE5")?,
769
770 c5_ask_size_1: parse_float("C5ASKSIZE1")?,
771 c5_ask_size_2: parse_float("C5ASKSIZE2")?,
772 c5_ask_size_3: parse_float("C5ASKSIZE3")?,
773 c5_ask_size_4: parse_float("C5ASKSIZE4")?,
774 c5_ask_size_5: parse_float("C5ASKSIZE5")?,
775
776 timestamp: parse_float("TIMESTAMP")?,
777 dealing_flag,
778 })
779 }
780}
781
782impl From<&ItemUpdate> for PriceData {
783 fn from(item_update: &ItemUpdate) -> Self {
784 PriceData::from_item_update(item_update).unwrap_or_default()
785 }
786}