use std::fmt;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ServiceConfigKey<'a> {
service_id: &'a str,
profile: &'a str,
env: &'a str,
}
impl<'a> ServiceConfigKey<'a> {
pub fn builder() -> builder::Builder<'a> {
Default::default()
}
pub fn service_id(&self) -> &'a str {
self.service_id
}
pub fn profile(&self) -> &'a str {
self.profile
}
pub fn env(&self) -> &'a str {
self.env
}
}
pub mod builder {
use super::ServiceConfigKey;
use std::fmt;
#[derive(Default, Debug)]
pub struct Builder<'a> {
service_id: Option<&'a str>,
profile: Option<&'a str>,
env: Option<&'a str>,
}
impl<'a> Builder<'a> {
pub fn service_id(mut self, service_id: &'a str) -> Self {
self.service_id = Some(service_id);
self
}
pub fn profile(mut self, profile: &'a str) -> Self {
self.profile = Some(profile);
self
}
pub fn env(mut self, env: &'a str) -> Self {
self.env = Some(env);
self
}
pub fn build(self) -> Result<ServiceConfigKey<'a>, Error> {
Ok(ServiceConfigKey {
service_id: self.service_id.ok_or_else(Error::missing_service_id)?,
profile: self.profile.ok_or_else(Error::missing_profile)?,
env: self.env.ok_or_else(Error::missing_env)?,
})
}
}
#[allow(clippy::enum_variant_names)]
#[derive(Debug)]
enum ErrorKind {
MissingServiceId,
MissingProfile,
MissingEnv,
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ErrorKind::MissingServiceId => write!(f, "missing required service-id"),
ErrorKind::MissingProfile => write!(f, "missing required active profile name"),
ErrorKind::MissingEnv => write!(f, "missing required environment variable name"),
}
}
}
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "couldn't build a ServiceEnvConfigKey: {}", self.kind)
}
}
impl std::error::Error for Error {}
impl Error {
pub fn missing_service_id() -> Self {
Self {
kind: ErrorKind::MissingServiceId,
}
}
pub fn missing_profile() -> Self {
Self {
kind: ErrorKind::MissingProfile,
}
}
pub fn missing_env() -> Self {
Self {
kind: ErrorKind::MissingEnv,
}
}
}
}
pub trait LoadServiceConfig: fmt::Debug + Send + Sync {
fn load_config(&self, key: ServiceConfigKey<'_>) -> Option<String>;
}