synwire_core/credentials/
env.rs1use crate::BoxFuture;
4use crate::credentials::SecretValue;
5use crate::credentials::traits::CredentialProvider;
6use crate::error::SynwireError;
7
8#[derive(Debug, Clone)]
18pub struct EnvCredentialProvider {
19 env_var: String,
20}
21
22impl EnvCredentialProvider {
23 pub fn new(env_var: impl Into<String>) -> Self {
25 Self {
26 env_var: env_var.into(),
27 }
28 }
29
30 pub fn env_var(&self) -> &str {
32 &self.env_var
33 }
34}
35
36impl CredentialProvider for EnvCredentialProvider {
37 fn get_credential(&self) -> BoxFuture<'_, Result<SecretValue, SynwireError>> {
38 Box::pin(async {
39 let value = std::env::var(&self.env_var).map_err(|_| SynwireError::Credential {
40 message: format!("environment variable {} not set", self.env_var),
41 })?;
42 Ok(SecretValue::new(value))
43 })
44 }
45}
46
47#[cfg(test)]
48#[allow(clippy::unwrap_used)]
49mod tests {
50 use super::*;
51
52 #[tokio::test]
53 async fn missing_env_var_returns_error() {
54 let provider = EnvCredentialProvider::new("SYNWIRE_NONEXISTENT_VAR_82a9f3c1d4e6b7");
56 let result = provider.get_credential().await;
57 assert!(result.is_err());
58 let err_msg = result.unwrap_err().to_string();
59 assert!(err_msg.contains("not set"));
60 }
61
62 #[tokio::test]
63 async fn get_credential_from_existing_env() {
64 let provider = EnvCredentialProvider::new("PATH");
66 let result = provider.get_credential().await;
67 assert!(result.is_ok());
68 assert!(!result.unwrap().expose().is_empty());
69 }
70
71 #[test]
72 fn env_var_accessor() {
73 let provider = EnvCredentialProvider::new("MY_KEY");
74 assert_eq!(provider.env_var(), "MY_KEY");
75 }
76}