use std::fmt;
use std::time::Duration;
use url::Url;
const DEFAULT_API_BASE_URL: &str = "https://api-t1.fyers.in/api/v3";
const DEFAULT_API_V2_BASE_URL: &str = "https://api.fyers.in/api/v2";
const DEFAULT_DATA_BASE_URL: &str = "https://api-t1.fyers.in/data";
const DEFAULT_SYMBOLS_BASE_URL: &str = "https://public.fyers.in/sym_details";
const DEFAULT_DATA_SOCKET_URL: &str = "wss://socket.fyers.in/hsm/v1-5/prod";
const DEFAULT_ORDER_SOCKET_URL: &str = "wss://socket.fyers.in/trade/v3";
const DEFAULT_TBT_SOCKET_URL: &str = "wss://rtsocket-api.fyers.in/versova";
const DEFAULT_TIMEOUT_SECS: u64 = 30;
#[derive(Clone, PartialEq, Eq)]
pub struct SecretString(String);
impl SecretString {
pub fn new(value: impl Into<String>) -> Self {
Self(value.into())
}
pub fn expose_secret(&self) -> &str {
&self.0
}
}
impl fmt::Debug for SecretString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("SecretString([redacted])")
}
}
#[derive(Clone, Debug)]
pub struct FyersConfig {
client_id: String,
secret_key: Option<SecretString>,
redirect_uri: Option<Url>,
access_token: Option<SecretString>,
api_base_url: Url,
api_v2_base_url: Url,
data_base_url: Url,
symbols_base_url: Url,
data_socket_url: Url,
order_socket_url: Url,
tbt_socket_url: Url,
timeout: Duration,
}
impl FyersConfig {
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
client_id: String,
secret_key: Option<SecretString>,
redirect_uri: Option<Url>,
access_token: Option<SecretString>,
api_base_url: Url,
api_v2_base_url: Url,
data_base_url: Url,
symbols_base_url: Url,
data_socket_url: Url,
order_socket_url: Url,
tbt_socket_url: Url,
timeout: Duration,
) -> Self {
Self {
client_id,
secret_key,
redirect_uri,
access_token,
api_base_url,
api_v2_base_url,
data_base_url,
symbols_base_url,
data_socket_url,
order_socket_url,
tbt_socket_url,
timeout,
}
}
pub fn client_id(&self) -> &str {
&self.client_id
}
pub fn secret_key(&self) -> Option<&SecretString> {
self.secret_key.as_ref()
}
pub fn redirect_uri(&self) -> Option<&Url> {
self.redirect_uri.as_ref()
}
pub fn access_token(&self) -> Option<&SecretString> {
self.access_token.as_ref()
}
pub fn api_base_url(&self) -> &Url {
&self.api_base_url
}
pub fn api_v2_base_url(&self) -> &Url {
&self.api_v2_base_url
}
pub fn data_base_url(&self) -> &Url {
&self.data_base_url
}
pub fn symbols_base_url(&self) -> &Url {
&self.symbols_base_url
}
pub fn data_socket_url(&self) -> &Url {
&self.data_socket_url
}
pub fn order_socket_url(&self) -> &Url {
&self.order_socket_url
}
pub fn tbt_socket_url(&self) -> &Url {
&self.tbt_socket_url
}
pub fn timeout(&self) -> Duration {
self.timeout
}
}
pub fn default_api_base_url() -> Url {
Url::parse(DEFAULT_API_BASE_URL).expect("default API base URL is valid")
}
pub fn default_api_v2_base_url() -> Url {
Url::parse(DEFAULT_API_V2_BASE_URL).expect("default API v2 base URL is valid")
}
pub fn default_data_base_url() -> Url {
Url::parse(DEFAULT_DATA_BASE_URL).expect("default data base URL is valid")
}
pub fn default_symbols_base_url() -> Url {
Url::parse(DEFAULT_SYMBOLS_BASE_URL).expect("default symbols base URL is valid")
}
pub fn default_data_socket_url() -> Url {
Url::parse(DEFAULT_DATA_SOCKET_URL).expect("default data socket URL is valid")
}
pub fn default_order_socket_url() -> Url {
Url::parse(DEFAULT_ORDER_SOCKET_URL).expect("default order socket URL is valid")
}
pub fn default_tbt_socket_url() -> Url {
Url::parse(DEFAULT_TBT_SOCKET_URL).expect("default TBT socket URL is valid")
}
pub fn default_timeout() -> Duration {
Duration::from_secs(DEFAULT_TIMEOUT_SECS)
}