use colored::Colorize;
use serde::{Deserialize, Serialize};
use std::fmt;
use crate::flake::interfaces::shellhooks::ShellHookSection;
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct FlakeConfig {
pub inputs: Vec<String>,
pub profiles: Vec<Profile>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Profile {
pub name: String,
pub packages: Vec<Package>,
pub env_vars: Vec<EnvVar>,
pub shell_hook: ShellHookSection,
}
impl Profile {
pub fn new(name: String) -> Self {
Self {
name,
packages: Vec::new(),
env_vars: Vec::new(),
shell_hook: ShellHookSection {
entries: Vec::new(),
indentation: " ".to_string(),
section_start: 0,
section_end: 0,
},
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Package {
pub name: String,
pub version: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct EnvVar {
pub name: String,
pub value: String,
}
impl EnvVar {
pub fn new(name: String, value: String) -> Self {
Self { name, value }
}
}
impl fmt::Display for EnvVar {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} = {}", self.name.cyan().bold(), self.value.green())
}
}
impl Package {
pub fn new(name: String) -> Self {
Self {
name,
version: Some("latest".to_string()),
}
}
}
impl fmt::Display for Package {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(version) = &self.version {
write!(
f,
"{} {}",
self.name.green(),
format!("({})", version).dimmed()
)
} else {
write!(f, "{}", self.name.green())
}
}
}
impl fmt::Display for Profile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "{}", self.name.bold().magenta())?;
if !self.packages.is_empty() {
writeln!(
f,
" {} {}",
"Packages:".dimmed(),
format!("({})", self.packages.len()).dimmed()
)?;
for pkg in &self.packages {
writeln!(f, " {} {}", "•".green(), pkg)?;
}
}
if !self.env_vars.is_empty() {
writeln!(
f,
" {} {}",
"Environment Variables:".dimmed(),
format!("({})", self.env_vars.len()).dimmed()
)?;
for env in &self.env_vars {
writeln!(f, " {} {}", "•".green(), env)?;
}
}
if !self.shell_hook.entries.is_empty() {
writeln!(f, " {}", "Commands:".dimmed())?;
for entry in &self.shell_hook.entries {
writeln!(f, " {} {}", "•".green(), entry.name.bold())?;
}
}
Ok(())
}
}
impl FlakeConfig {
pub fn _display_packages(&self) {
if self.profiles.is_empty() {
println!("{}", "No profiles defined".yellow());
return;
}
println!(
"{} {}",
"Profiles:".bold().cyan(),
format!("({})", self.profiles.len()).dimmed()
);
println!();
for profile in &self.profiles {
println!("{}", profile.name.bold().magenta());
if !profile.packages.is_empty() {
println!(
" {} {}",
"Packages:".dimmed(),
format!("({})", profile.packages.len()).dimmed()
);
for pkg in &profile.packages {
println!(" {} {}", "•".green(), pkg);
}
} else {
println!(" {}", "No packages".dimmed());
}
println!();
}
}
pub fn display_env_vars(&self) {
if self.profiles.is_empty() {
println!("{}", "No profiles defined".yellow());
return;
}
println!("{}", "Environment Variables by Profile:".bold().cyan());
println!();
for profile in &self.profiles {
if !profile.env_vars.is_empty() {
println!(
"{} {}",
profile.name.bold().magenta(),
format!("({})", profile.env_vars.len()).dimmed()
);
for env_var in &profile.env_vars {
println!(" {} {}", "•".green(), env_var);
}
println!();
}
}
}
pub fn display_shell_hooks(&self) {
if self.profiles.is_empty() {
println!("{}", "No profiles defined".yellow());
return;
}
println!("{}", "Shell Hooks by Profile:".bold().cyan());
println!();
for profile in &self.profiles {
if !profile.shell_hook.entries.is_empty() {
println!("{}", profile.name.bold().magenta());
for entry in &profile.shell_hook.entries {
println!(" {} {}", "•".green(), entry.name.bold());
}
}
}
}
}
impl fmt::Display for FlakeConfig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "{}", "Flake Configuration".bold().cyan())?;
writeln!(f, "{}", "===================".cyan())?;
writeln!(f)?;
if !self.inputs.is_empty() {
writeln!(f, "{}", "Inputs:".bold().yellow())?;
for input in &self.inputs {
writeln!(f, " {} {}", "•".green(), input)?;
}
writeln!(f)?;
}
if !self.profiles.is_empty() {
writeln!(
f,
"{} {}",
"Profiles:".bold().yellow(),
format!("({})", self.profiles.len()).dimmed()
)?;
for profile in &self.profiles {
writeln!(f, "{}", profile)?;
}
}
Ok(())
}
}