use std::borrow::Cow;
use std::env::var;
use std::error::Error;
use std::fmt::Display;
use std::fs::read_to_string;
#[derive(Debug)]
pub enum SecretError {
Load { path: String, error: std::io::Error },
MissingEnvVar(String),
}
impl Display for SecretError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SecretError::Load { path, error } => {
write!(f, "failed to load token from {path}: {error:#}")
}
SecretError::MissingEnvVar(var) => {
write!(f, "environment variable {var} referenced but not set")
}
}
}
}
impl Error for SecretError {}
pub fn load(path: &str) -> Result<String, SecretError> {
let file = if path.contains("$CREDENTIALS_DIRECTORY") {
let dir = var("CREDENTIALS_DIRECTORY")
.map_err(|_| SecretError::MissingEnvVar("$CREDENTIALS_DIRECTORY".into()))?;
Cow::Owned(path.replace("$CREDENTIALS_DIRECTORY", &dir))
} else {
Cow::Borrowed(path)
};
let mut content = read_to_string(file.as_ref()).map_err(|error| SecretError::Load {
path: file.into(),
error,
})?;
content.truncate(content.trim_end().len()); Ok(content)
}