ig_client/application/services/
types.rs

1use crate::application::models::market::{MarketData, MarketNode};
2use crate::error::AppError;
3use crate::presentation::InstrumentType;
4use chrono::{DateTime, Utc};
5use pretty_simple_display::DisplaySimple;
6use serde::{Deserialize, Serialize};
7
8/// Result type for listener operations that don't return a value but may return an error
9pub type ListenerResult = Result<(), AppError>;
10
11/// A data structure representing an entry in the database, containing details about a financial trading instrument.
12///
13/// # Fields
14///
15/// * `symbol` - The unique identifier or trading symbol for this financial instrument.
16/// * `epic` - The Epic identifier as provided by the exchange for this instrument.
17/// * `name` - A human-readable name that describes the financial instrument.
18/// * `instrument_type` - The classification or type of the financial instrument (e.g., stock, bond, future, etc.).
19/// * `exchange` - The name of the exchange where this instrument is traded.
20/// * `expiry` - The expiration date and time of the instrument, if applicable.
21/// * `last_update` - The `DateTime` indicating when this record was last updated.
22///
23/// This structure includes traits such as `Debug`, `Clone`, `Serialize`, `Deserialize`, `PartialEq`, `Eq`, `Hash`, and `Default`
24/// for ease of use, serialization, comparison, and hashing operations.
25#[derive(Debug, DisplaySimple, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Default)]
26pub struct DBEntry {
27    /// The trading symbol identifier
28    pub symbol: String,
29    /// The Epic identifier used by the exchange
30    pub epic: String,
31    /// Human-readable name of the instrument
32    pub name: String,
33    /// Instrument type classification
34    pub instrument_type: InstrumentType,
35    /// The exchange where this instrument is traded
36    pub exchange: String,
37    /// Expiration date and time for the instrument
38    pub expiry: String,
39    /// Timestamp of the last update to this record
40    pub last_update: DateTime<Utc>,
41}
42
43impl From<MarketNode> for DBEntry {
44    fn from(value: MarketNode) -> Self {
45        let mut entry = DBEntry::default();
46        if !value.markets.is_empty() {
47            let market = &value.markets[0];
48            entry.symbol = market
49                .epic
50                .split('.')
51                .nth(2)
52                .unwrap_or_default()
53                .to_string();
54            entry.epic = market.epic.clone();
55            entry.name = market.instrument_name.clone();
56            entry.instrument_type = market.instrument_type;
57            entry.exchange = "IG".to_string();
58            entry.expiry = market.expiry.clone();
59            entry.last_update = Utc::now();
60        }
61        entry
62    }
63}
64
65impl From<MarketData> for DBEntry {
66    fn from(market: MarketData) -> Self {
67        DBEntry {
68            symbol: market
69                .epic
70                .split('.')
71                .nth(2)
72                .unwrap_or_default()
73                .to_string(),
74            epic: market.epic.clone(),
75            name: market.instrument_name.clone(),
76            instrument_type: market.instrument_type,
77            exchange: "IG".to_string(),
78            expiry: market.expiry.clone(),
79            last_update: Utc::now(),
80        }
81    }
82}
83
84impl From<&MarketNode> for DBEntry {
85    fn from(value: &MarketNode) -> Self {
86        DBEntry::from(value.clone())
87    }
88}
89
90impl From<&MarketData> for DBEntry {
91    fn from(market: &MarketData) -> Self {
92        DBEntry::from(market.clone())
93    }
94}