cipherstash-client 0.12.5

The official CipherStash SDK
Documentation
use url::Url;

use super::defaults::DEFAULT_CTS_BASE_URL;
use super::errors::ConfigError;
use super::vars::CS_CTS_HOST;

pub struct CtsConfigBuilder {
    base_url: String,
}

impl Default for CtsConfigBuilder {
    fn default() -> Self {
        Self {
            base_url: DEFAULT_CTS_BASE_URL.to_string(),
        }
    }
}

impl CtsConfigBuilder {
    /// Hydrate the configuration using environment variables
    pub fn with_env(mut self) -> Self {
        for name in CS_CTS_HOST {
            if let Ok(value) = std::env::var(name) {
                self.base_url = value;
                break;
            }
        }

        self
    }

    pub fn build(self) -> Result<CtsConfig, ConfigError> {
        Ok(CtsConfig {
            base_url: self.base_url.parse()?,
        })
    }

    pub fn base_url(mut self, value: &str) -> Self {
        self.base_url = value.to_string();
        self
    }
}

#[derive(Clone)]
pub struct CtsConfig {
    base_url: Url,
}

impl CtsConfig {
    /// Return a [`CtsConfigBuilder`] to build a [`CtsConfig`] used to configure access to CTS
    ///
    /// ```rust
    /// # use cipherstash_client::CtsConfig;
    /// let config = CtsConfig::builder()
    ///   .with_env()
    ///   .build()
    ///   .expect("failed to create config");
    /// ```
    pub fn builder() -> CtsConfigBuilder {
        CtsConfigBuilder::default()
    }

    /// Return the base URL of the CTS API
    pub fn base_url(&self) -> Url {
        self.base_url.clone()
    }
}

#[cfg(test)]
mod tests {
    use sealed_test::prelude::*;

    use super::*;

    #[sealed_test]
    fn test_with_default_values() {
        let default_base_url: Url = DEFAULT_CTS_BASE_URL.parse().unwrap();
        let cts_config = CtsConfig::builder().build().unwrap();

        assert_eq!(cts_config.base_url(), default_base_url);
    }

    #[sealed_test]
    fn test_with_env_fallbacks_to_default_values() {
        std::env::remove_var(CS_CTS_HOST[0]);

        let default_base_url: Url = DEFAULT_CTS_BASE_URL.parse().unwrap();
        let cts_config = CtsConfig::builder().with_env().build().unwrap();

        assert_eq!(cts_config.base_url(), default_base_url);
    }

    #[sealed_test]
    fn test_with_env_values() {
        std::env::set_var(
            CS_CTS_HOST[0],
            "https://custom-idp.from-env.cipherstash.com",
        );

        let env_base_url: Url = "https://custom-idp.from-env.cipherstash.com"
            .parse()
            .unwrap();
        let cts_config = CtsConfig::builder().with_env().build().unwrap();

        assert_eq!(cts_config.base_url(), env_base_url);
    }

    #[sealed_test]
    fn test_with_override() {
        std::env::set_var(
            CS_CTS_HOST[0],
            "https://custom-idp.from-env.cipherstash.com",
        );

        let override_base_url: Url = "https://custom-idp.from-override.cipherstash.com"
            .parse()
            .unwrap();
        let cts_config = CtsConfig::builder()
            .with_env()
            .base_url("https://custom-idp.from-override.cipherstash.com")
            .build()
            .unwrap();

        assert_eq!(cts_config.base_url(), override_base_url);
    }
}