use std::net::{IpAddr, Ipv4Addr};
use std::time::Duration;
pub const DEFAULT_HTTP_TIMEOUT: Duration = Duration::from_secs(120);
pub const DEFAULT_QUERY_TIMEOUT: Duration = Duration::from_secs(3600);
#[derive(Clone, Debug, Default)]
pub enum BrowserLaunch {
#[default]
Auto,
Command(Vec<String>),
Manual,
}
#[derive(Clone, Debug)]
pub struct BrowserConfig {
pub launch: BrowserLaunch,
pub callback_addr: IpAddr,
pub callback_port: u16,
}
impl Default for BrowserConfig {
fn default() -> Self {
Self {
launch: BrowserLaunch::Auto,
callback_addr: IpAddr::V4(Ipv4Addr::LOCALHOST),
callback_port: 0,
}
}
}
#[derive(Clone, Debug)]
pub enum AuthMethod {
ExternalBrowser(BrowserConfig),
}
#[derive(Clone, Debug)]
pub struct SnowflakeClientConfig {
pub account: String,
pub user: String,
pub auth: AuthMethod,
pub warehouse: Option<String>,
pub role: Option<String>,
pub database: Option<String>,
pub schema: Option<String>,
pub host: Option<String>,
pub http_timeout: Duration,
pub query_timeout: Duration,
}
impl SnowflakeClientConfig {
#[must_use]
pub fn external_browser(account: impl Into<String>, user: impl Into<String>) -> Self {
Self {
account: account.into(),
user: user.into(),
auth: AuthMethod::ExternalBrowser(BrowserConfig::default()),
warehouse: None,
role: None,
database: None,
schema: None,
host: None,
http_timeout: DEFAULT_HTTP_TIMEOUT,
query_timeout: DEFAULT_QUERY_TIMEOUT,
}
}
#[must_use]
pub fn api_host(&self) -> String {
if let Some(host) = &self.host {
return host.clone();
}
let account = self.account.trim().to_lowercase().replace('_', "-");
format!("{account}.snowflakecomputing.com")
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn api_host_maps_account_identifiers() {
let host =
|account: &str| SnowflakeClientConfig::external_browser(account, "me").api_host();
assert_eq!(host("MyAcct"), "myacct.snowflakecomputing.com");
assert_eq!(host("my_org-acct"), "my-org-acct.snowflakecomputing.com");
assert_eq!(
host("xy12345.us-east-1.aws"),
"xy12345.us-east-1.aws.snowflakecomputing.com"
);
}
#[test]
fn api_host_override_wins() {
let cfg = SnowflakeClientConfig {
host: Some("acct.privatelink.snowflakecomputing.com".to_string()),
..SnowflakeClientConfig::external_browser("MyAcct", "me")
};
assert_eq!(cfg.api_host(), "acct.privatelink.snowflakecomputing.com");
}
#[test]
fn default_http_timeout_is_set() {
let cfg = SnowflakeClientConfig::external_browser("a", "b");
assert_eq!(cfg.http_timeout, DEFAULT_HTTP_TIMEOUT);
}
}