ig_client/session/
response.rs

1/// Response structure for session-related API calls
2#[derive(serde::Deserialize)]
3pub struct SessionResp {
4    /// Account ID associated with the session
5    #[serde(alias = "accountId")]
6    #[serde(alias = "currentAccountId")]
7    pub account_id: String,
8
9    /// Client ID provided by the API
10    #[serde(alias = "clientId")]
11    pub client_id: Option<String>,
12    /// Timezone offset in hours
13    #[serde(alias = "timezoneOffset")]
14    pub timezone_offset: Option<i32>,
15}
16
17/// Request model for switching the active account
18#[derive(serde::Serialize)]
19pub struct AccountSwitchRequest {
20    /// The identifier of the account being switched to
21    #[serde(rename = "accountId")]
22    pub account_id: String,
23    /// True if the specified account is to be set as the new default account
24    #[serde(rename = "defaultAccount")]
25    pub default_account: Option<bool>,
26}
27
28/// Response model for account switch operation
29#[derive(serde::Deserialize, Debug)]
30pub struct AccountSwitchResponse {
31    /// Whether dealing is enabled for the account
32    #[serde(rename = "dealingEnabled")]
33    pub dealing_enabled: Option<bool>,
34    /// Whether the user has active demo accounts
35    #[serde(rename = "hasActiveDemoAccounts")]
36    pub has_active_demo_accounts: Option<bool>,
37    /// Whether the user has active live accounts
38    #[serde(rename = "hasActiveLiveAccounts")]
39    pub has_active_live_accounts: Option<bool>,
40    /// Whether trailing stops are enabled for the account
41    #[serde(rename = "trailingStopsEnabled")]
42    pub trailing_stops_enabled: Option<bool>,
43}
44
45/// OAuth token information returned by API v3
46#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
47pub struct OAuthToken {
48    /// OAuth access token
49    pub access_token: String,
50    /// OAuth refresh token
51    pub refresh_token: String,
52    /// Token scope
53    pub scope: String,
54    /// Token type (typically "Bearer")
55    pub token_type: String,
56    /// Token expiry time in seconds
57    pub expires_in: String,
58    /// Timestamp when this token was created (for expiry calculation)
59    #[serde(skip, default = "chrono::Utc::now")]
60    pub created_at: chrono::DateTime<chrono::Utc>,
61}
62
63impl OAuthToken {
64    /// Checks if the OAuth token is expired or will expire soon
65    ///
66    /// # Arguments
67    /// * `margin_seconds` - Safety margin in seconds before actual expiry
68    ///
69    /// # Returns
70    /// `true` if the token is expired or will expire within the margin, `false` otherwise
71    pub fn is_expired(&self, margin_seconds: i64) -> bool {
72        let expires_in_secs = self.expires_in.parse::<i64>().unwrap_or(0);
73        let expiry_time = self.created_at + chrono::Duration::seconds(expires_in_secs);
74        let now = chrono::Utc::now();
75        let margin = chrono::Duration::seconds(margin_seconds);
76
77        expiry_time - margin <= now
78    }
79}
80
81/// Response structure for session API v3 calls
82#[derive(serde::Deserialize, Debug)]
83pub struct SessionV3Resp {
84    /// Client ID provided by the API
85    #[serde(rename = "clientId")]
86    pub client_id: String,
87    /// Account ID associated with the session
88    #[serde(rename = "accountId")]
89    pub account_id: String,
90    /// Timezone offset in hours
91    #[serde(rename = "timezoneOffset")]
92    pub timezone_offset: i32,
93    /// Lightstreamer endpoint for subscribing to account and price updates
94    #[serde(rename = "lightstreamerEndpoint")]
95    pub lightstreamer_endpoint: String,
96    /// OAuth token information
97    #[serde(rename = "oauthToken")]
98    pub oauth_token: OAuthToken,
99}