use crate::{Error, Result};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EnvironmentFormat {
Yml,
Yaml,
Properties,
}
impl EnvironmentFormat {
pub(crate) fn suffix(self) -> &'static str {
match self {
Self::Yml => ".yml",
Self::Yaml => ".yaml",
Self::Properties => ".properties",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EnvironmentRequest {
application: String,
profiles: Vec<String>,
label: Option<String>,
resolve_placeholders: bool,
}
impl EnvironmentRequest {
pub fn new<A, I, P>(application: A, profiles: I) -> Result<Self>
where
A: Into<String>,
I: IntoIterator<Item = P>,
P: Into<String>,
{
let application = sanitize_required(application.into(), Error::EmptyApplication)?;
let profiles = sanitize_profiles(profiles)?;
Ok(Self {
application,
profiles,
label: None,
resolve_placeholders: false,
})
}
pub fn label(mut self, label: impl Into<String>) -> Self {
let label = label.into().trim().to_string();
self.label = if label.is_empty() { None } else { Some(label) };
self
}
pub fn resolve_placeholders(mut self, enabled: bool) -> Self {
self.resolve_placeholders = enabled;
self
}
pub fn application(&self) -> &str {
&self.application
}
pub fn profiles(&self) -> &[String] {
&self.profiles
}
pub fn label_ref(&self) -> Option<&str> {
self.label.as_deref()
}
pub fn resolve_placeholders_enabled(&self) -> bool {
self.resolve_placeholders
}
pub(crate) fn joined_profiles(&self) -> String {
self.profiles.join(",")
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ResourceRequest {
application: String,
profiles: Vec<String>,
label: Option<String>,
path: String,
}
impl ResourceRequest {
pub fn new<A, I, P, R>(application: A, profiles: I, path: R) -> Result<Self>
where
A: Into<String>,
I: IntoIterator<Item = P>,
P: Into<String>,
R: Into<String>,
{
let application = sanitize_required(application.into(), Error::EmptyApplication)?;
let profiles = sanitize_profiles(profiles)?;
let path = sanitize_required(
normalize_resource_path(path.into()),
Error::EmptyResourcePath,
)?;
Ok(Self {
application,
profiles,
label: None,
path,
})
}
pub fn label(mut self, label: impl Into<String>) -> Self {
let label = label.into().trim().to_string();
self.label = if label.is_empty() { None } else { Some(label) };
self
}
pub fn application(&self) -> &str {
&self.application
}
pub fn profiles(&self) -> &[String] {
&self.profiles
}
pub fn label_ref(&self) -> Option<&str> {
self.label.as_deref()
}
pub fn path(&self) -> &str {
&self.path
}
pub(crate) fn joined_profiles(&self) -> String {
self.profiles.join(",")
}
pub(crate) fn path_segments(&self) -> Vec<String> {
self.path
.split('/')
.filter(|segment| !segment.is_empty())
.map(ToOwned::to_owned)
.collect()
}
}
fn sanitize_profiles<I, P>(profiles: I) -> Result<Vec<String>>
where
I: IntoIterator<Item = P>,
P: Into<String>,
{
let sanitized: Vec<String> = profiles
.into_iter()
.map(Into::into)
.map(|profile| profile.trim().to_string())
.filter(|profile| !profile.is_empty())
.collect();
if sanitized.is_empty() {
Err(Error::EmptyProfiles)
} else {
Ok(sanitized)
}
}
fn sanitize_required(value: String, error: Error) -> Result<String> {
let value = value.trim().to_string();
if value.is_empty() {
Err(error)
} else {
Ok(value)
}
}
fn normalize_resource_path(path: String) -> String {
path.replace('\\', "/").trim_matches('/').to_string()
}