Skip to main content

keygen_rs/
config.rs

1//! Global configuration management for keygen-rs.
2//!
3//! This module provides thread-safe global configuration for the Keygen API client.
4//! Configuration can be set once and accessed throughout the application.
5//!
6//! # Example
7//! ```no_run
8//! use keygen_rs::config::{set_config, KeygenConfig};
9//!
10//! set_config(KeygenConfig {
11//!     account: "your-account-id".to_string(),
12//!     product: "your-product-id".to_string(),
13//!     license_key: Some("your-license-key".to_string()),
14//!     public_key: Some("your-public-key".to_string()),
15//!     ..Default::default()
16//! }).expect("Failed to set config");
17//! ```
18
19use crate::errors::Error;
20use lazy_static::lazy_static;
21use std::sync::RwLock;
22
23#[derive(Clone, Debug)]
24pub struct KeygenConfig {
25    // Common configuration
26    pub api_url: String,
27    pub api_version: String,
28    pub api_prefix: String,
29    pub account: String,
30    pub environment: Option<String>,
31    pub user_agent: Option<String>,
32
33    // License Key Authentication configuration
34    #[cfg(feature = "license-key")]
35    pub product: String,
36    #[cfg(feature = "license-key")]
37    pub package: String,
38    #[cfg(feature = "license-key")]
39    pub license_key: Option<String>,
40    #[cfg(feature = "license-key")]
41    pub public_key: Option<String>,
42    #[cfg(feature = "license-key")]
43    pub platform: Option<String>,
44    #[cfg(feature = "license-key")]
45    pub max_clock_drift: Option<i64>,
46    #[cfg(feature = "license-key")]
47    pub verify_keygen_signature: Option<bool>,
48
49    // Token Authentication configuration
50    #[cfg(feature = "token")]
51    pub token: Option<String>,
52}
53
54impl Default for KeygenConfig {
55    fn default() -> Self {
56        KeygenConfig {
57            // Common defaults
58            api_url: "https://api.keygen.sh".to_string(),
59            api_version: "1.7".to_string(),
60            api_prefix: "v1".to_string(),
61            account: String::new(),
62            environment: None,
63            user_agent: None,
64
65            // License Key Authentication defaults
66            #[cfg(feature = "license-key")]
67            product: String::new(),
68            #[cfg(feature = "license-key")]
69            package: String::new(),
70            #[cfg(feature = "license-key")]
71            license_key: None,
72            #[cfg(feature = "license-key")]
73            public_key: None,
74            #[cfg(feature = "license-key")]
75            platform: None,
76            #[cfg(feature = "license-key")]
77            max_clock_drift: Some(5),
78            #[cfg(feature = "license-key")]
79            verify_keygen_signature: Some(true),
80
81            // Token Authentication defaults
82            #[cfg(feature = "token")]
83            token: None,
84        }
85    }
86}
87
88impl KeygenConfig {
89    /// Create a license key authentication configuration
90    #[cfg(feature = "license-key")]
91    pub fn license_key(
92        account: String,
93        product: String,
94        license_key: String,
95        public_key: String,
96    ) -> Self {
97        KeygenConfig {
98            account,
99            product,
100            license_key: Some(license_key),
101            public_key: Some(public_key),
102            ..Default::default()
103        }
104    }
105
106    /// Create a token authentication configuration
107    #[cfg(feature = "token")]
108    pub fn token(account: String, token: String) -> Self {
109        KeygenConfig {
110            account,
111            token: Some(token),
112            ..Default::default()
113        }
114    }
115}
116
117lazy_static! {
118    static ref KEYGEN_CONFIG: RwLock<KeygenConfig> = RwLock::new(KeygenConfig::default());
119}
120
121pub fn get_config() -> Result<KeygenConfig, Error> {
122    KEYGEN_CONFIG
123        .read()
124        .map_err(|_| Error::UnexpectedError("Config lock poisoned".to_string()))?
125        .clone()
126        .into()
127}
128
129impl From<KeygenConfig> for Result<KeygenConfig, Error> {
130    fn from(config: KeygenConfig) -> Self {
131        Ok(config)
132    }
133}
134
135fn update_config<F>(f: F) -> Result<(), Error>
136where
137    F: FnOnce(&mut KeygenConfig),
138{
139    let mut current_config = KEYGEN_CONFIG
140        .write()
141        .map_err(|_| Error::UnexpectedError("Config lock poisoned".to_string()))?;
142    f(&mut current_config);
143    Ok(())
144}
145
146pub fn set_config(config: KeygenConfig) -> Result<(), Error> {
147    update_config(|current| *current = config)
148}
149
150pub fn set_api_url(api_url: &str) -> Result<(), Error> {
151    update_config(|cfg| cfg.api_url = api_url.to_string())
152}
153
154pub fn set_api_version(api_version: &str) -> Result<(), Error> {
155    update_config(|cfg| cfg.api_version = api_version.to_string())
156}
157
158pub fn set_api_prefix(api_prefix: &str) -> Result<(), Error> {
159    update_config(|cfg| cfg.api_prefix = api_prefix.to_string())
160}
161
162pub fn set_account(account: &str) -> Result<(), Error> {
163    update_config(|cfg| cfg.account = account.to_string())
164}
165
166#[cfg(feature = "license-key")]
167pub fn set_product(product: &str) -> Result<(), Error> {
168    update_config(|cfg| cfg.product = product.to_string())
169}
170
171#[cfg(feature = "license-key")]
172pub fn set_package(package: &str) -> Result<(), Error> {
173    update_config(|cfg| cfg.package = package.to_string())
174}
175
176pub fn set_environment(environment: &str) -> Result<(), Error> {
177    update_config(|cfg| cfg.environment = Some(environment.to_string()))
178}
179
180#[cfg(feature = "license-key")]
181pub fn set_license_key(license_key: &str) -> Result<(), Error> {
182    update_config(|cfg| cfg.license_key = Some(license_key.to_string()))
183}
184
185#[cfg(feature = "token")]
186pub fn set_token(token: &str) -> Result<(), Error> {
187    update_config(|cfg| cfg.token = Some(token.to_string()))
188}
189
190#[cfg(feature = "license-key")]
191pub fn set_public_key(public_key: &str) -> Result<(), Error> {
192    update_config(|cfg| cfg.public_key = Some(public_key.to_string()))
193}
194
195#[cfg(feature = "license-key")]
196pub fn set_platform(platform: &str) -> Result<(), Error> {
197    update_config(|cfg| cfg.platform = Some(platform.to_string()))
198}
199
200pub fn set_user_agent(user_agent: &str) -> Result<(), Error> {
201    update_config(|cfg| cfg.user_agent = Some(user_agent.to_string()))
202}
203
204#[cfg(feature = "license-key")]
205pub fn set_max_clock_drift(max_clock_drift: i64) -> Result<(), Error> {
206    update_config(|cfg| cfg.max_clock_drift = Some(max_clock_drift))
207}
208
209pub fn reset_config() -> Result<(), Error> {
210    update_config(|cfg| *cfg = KeygenConfig::default())
211}