use std::{path::PathBuf, str::FromStr};
use clap::{Parser, ValueEnum};
pub mod utils;
pub mod merge;
#[derive(Parser, Debug, Clone)]
pub struct Args {
#[command(subcommand)]
pub command: Subcommand,
}
#[derive(clap::Subcommand, Debug, Clone)]
pub enum Subcommand {
Merge(MergeArgs),
}
#[derive(clap::Args, Debug, Clone)]
pub struct MergeArgs {
#[arg(short, long)]
pub file: Option<PathBuf>,
#[arg(short, long)]
pub json: Option<String>,
#[arg(short, long)]
pub yaml: Option<String>,
#[arg(short, long)]
pub encoding: Option<Encoding>,
#[arg(long = "var", short = 'v')]
pub template_vars: Vec<TemplateVar>,
#[arg(short = 'o', long = "output-file")]
pub output: Option<PathBuf>,
#[arg(long = "output-encoding", short = 'E')]
pub output_format: Option<Encoding>,
#[arg(long = "working-dir", short = 'w')]
pub working_directory: Option<PathBuf>,
#[arg(long = "verbose", short = 'V', action)]
pub verbose: bool,
#[arg(long = "v2", action)]
pub use_version_2: bool,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum)]
pub enum Encoding {
Json,
Yaml,
Yml,
}
#[derive(Debug, Clone)]
pub struct TemplateVar {
pub key: String,
pub value: String,
}
impl FromStr for TemplateVar {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.splitn(2, '=');
let key = parts
.next()
.ok_or_else(|| format!("Missing key in '{}'", s))?;
let value = parts
.next()
.ok_or_else(|| format!("Missing value in '{}'. Expected format: key=value", s))?;
Ok(Self {
key: key.to_string(),
value: value.to_string(),
})
}
}
impl MergeArgs {
pub fn working_dir(&self) -> PathBuf {
if let Some(path) = &self.working_directory {
return path.clone();
}
std::env::current_dir().unwrap()
}
pub fn relative_path(&self, path: &PathBuf) -> PathBuf {
if path.is_absolute() {
return path.clone();
}
self.working_dir().join(path)
}
}