use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use crate::{PleaseConfig, PleaseProjectConfig, PleaseSettingsConfig};
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct PleaseProjectConfigBuilder {
pub owner: Option<String>,
pub repository: Option<String>,
pub source: Option<PathBuf>,
pub branch: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct PleaseSettingsConfigBuilder {
pub api_url: Option<String>,
pub git_username: Option<String>,
pub git_email: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct PleaseConfigBuilder {
pub project: Option<PleaseProjectConfigBuilder>,
pub settings: Option<PleaseSettingsConfigBuilder>,
}
impl PleaseConfigBuilder {
pub fn merge(&mut self, config: &PleaseConfigBuilder) -> &Self {
let config = config.clone();
let mut fproject = match self.project.clone() {
None => PleaseProjectConfigBuilder::default(),
Some(project) => project,
};
let mut fsettings = match self.settings.clone() {
None => PleaseSettingsConfigBuilder::default(),
Some(settings) => settings,
};
if let Some(project) = config.project {
if let Some(owner) = project.owner {
fproject.owner = Some(owner);
}
if let Some(repository) = project.repository {
fproject.repository = Some(repository);
}
if let Some(source) = project.source {
fproject.source = Some(source);
}
if let Some(branch) = project.branch {
fproject.branch = Some(branch);
}
self.project = Some(fproject);
}
if let Some(settings) = config.settings {
if let Some(api_url) = settings.api_url {
fsettings.api_url = Some(api_url);
}
if let Some(git_username) = settings.git_username {
fsettings.git_username = Some(git_username);
}
if let Some(git_email) = settings.git_email {
fsettings.git_email = Some(git_email);
}
self.settings = Some(fsettings);
}
self
}
}
impl TryFrom<PleaseConfigBuilder> for PleaseConfig {
type Error = anyhow::Error;
fn try_from(value: PleaseConfigBuilder) -> Result<Self, Self::Error> {
Ok(Self {
project: value
.project
.ok_or(value_is_missing("project"))?
.try_into()?,
settings: value
.settings
.ok_or(value_is_missing("settings"))?
.try_into()?,
})
}
}
impl TryFrom<PleaseProjectConfigBuilder> for PleaseProjectConfig {
type Error = anyhow::Error;
fn try_from(value: PleaseProjectConfigBuilder) -> Result<Self, Self::Error> {
Ok(Self {
owner: value.owner.ok_or(value_is_missing("owner"))?,
repository: value.repository.ok_or(value_is_missing("repository"))?,
source: value.source.ok_or(value_is_missing("source"))?,
branch: value.branch.ok_or(value_is_missing("branch"))?,
})
}
}
impl TryFrom<PleaseSettingsConfigBuilder> for PleaseSettingsConfig {
type Error = anyhow::Error;
fn try_from(value: PleaseSettingsConfigBuilder) -> Result<Self, Self::Error> {
Ok(Self {
api_url: value.api_url.ok_or(value_is_missing("api_url"))?,
git_username: value.git_username.clone(),
git_email: value.git_username.clone(),
})
}
}
fn value_is_missing(message: &str) -> anyhow::Error {
anyhow::anyhow!(
"{} is required, pass via. cli, env or config file, see --help",
message.to_string()
)
}