use crate::error::{GvcError, Result};
use colored::Colorize;
use std::fmt;
use std::io::{self, Write};
#[derive(Copy, Clone)]
enum UpdateCategory {
Version,
Library,
Plugin,
}
impl fmt::Display for UpdateCategory {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = match self {
UpdateCategory::Version => "Version",
UpdateCategory::Library => "Library",
UpdateCategory::Plugin => "Plugin",
};
f.write_str(label)
}
}
pub struct UpdateInteraction {
enabled: bool,
apply_all: bool,
}
impl UpdateInteraction {
pub fn new(enabled: bool) -> Self {
Self {
enabled,
apply_all: false,
}
}
pub fn is_enabled(&self) -> bool {
self.enabled
}
pub fn confirm_version(&mut self, name: &str, old: &str, new: &str) -> Result<bool> {
self.confirm(UpdateCategory::Version, name, old, new)
}
pub fn confirm_library(&mut self, name: &str, old: &str, new: &str) -> Result<bool> {
self.confirm(UpdateCategory::Library, name, old, new)
}
pub fn confirm_plugin(&mut self, name: &str, old: &str, new: &str) -> Result<bool> {
self.confirm(UpdateCategory::Plugin, name, old, new)
}
fn confirm(
&mut self,
category: UpdateCategory,
name: &str,
old: &str,
new: &str,
) -> Result<bool> {
if !self.enabled {
return Ok(true);
}
let category_label = format!("[{}]", category);
crate::outln!(
"\n{} {} {} {} to {}",
category_label.cyan().bold(),
name.white().bold(),
"from".dimmed(),
old.red(),
new.green().bold()
);
if self.apply_all {
crate::outln!("{}", "Auto-applying (previously selected 'all').".dimmed());
return Ok(true);
}
loop {
crate::out!("{}", "Apply this update? [Y/n/a/q]: ".bold());
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
let decision = input.trim().to_lowercase();
match decision.as_str() {
"" | "y" | "yes" => {
return Ok(true);
}
"n" | "no" => {
crate::outln!("{}", "Skipping this update.".dimmed());
return Ok(false);
}
"a" | "all" => {
crate::outln!(
"{}",
"Applying this and all remaining updates.".green().bold()
);
self.apply_all = true;
return Ok(true);
}
"q" | "quit" => {
crate::outln!("{}", "Stopping update process at user request.".yellow());
return Err(GvcError::UserCancelled);
}
_ => {
crate::outln!(
"{}",
"Please answer with y(es), n(o), a(ll), or q(quit).".red()
);
}
}
}
}
}