use std::env; pub const KEYRING_SERVICE: &str = "system-update"; pub const KEYRING_ACCOUNT: &str = "api-token"; pub fn keyring_identity() -> (&'static str, &'static str) { (KEYRING_SERVICE, KEYRING_ACCOUNT) } #[derive(Debug, Clone, PartialEq, Eq)] pub enum TokenSource { CliArgument(String), Environment(Option), } impl TokenSource { pub fn from_env() -> Self { Self::Environment(env::var("SYSTEM_UPDATE_TOKEN").ok()) } pub fn load(self) -> Option { match self { Self::CliArgument(token) => clean_token(token), Self::Environment(token) => token.and_then(clean_token), } } } fn clean_token(token: String) -> Option { let trimmed = token.trim().to_string(); if trimmed.is_empty() { None } else { Some(trimmed) } } #[cfg(test)] mod tests { use super::*; #[test] fn trims_cli_token() { assert_eq!( TokenSource::CliArgument(" su_token ".to_string()).load(), Some("su_token".to_string()) ); } #[test] fn ignores_empty_token() { assert_eq!(TokenSource::CliArgument(" ".to_string()).load(), None); } #[test] fn documents_future_keyring_identity() { assert_eq!(keyring_identity(), ("system-update", "api-token")); } }