use std::fmt::Display;
use chrono::Local;
use git2::{Signature, Time};
use crate::Autosave;
pub struct AutosaveFilters<'a> {
pub signature: &'a Signature<'a>,
pub branch: &'a str,
pub earliest_time: Time,
pub repo_id: &'a str,
pub all_users: bool,
pub all_branches: bool,
pub anytime: bool,
pub all_devices: bool,
}
struct AutosaveOption {
text: String,
value: Autosave,
}
impl Display for AutosaveOption {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.text.fmt(f)
}
}
pub fn filter_autosaves(
autosaves: impl IntoIterator<Item = Autosave>,
filters: AutosaveFilters<'_>,
) -> impl Iterator<Item = Autosave> {
let AutosaveFilters {
all_users,
signature,
all_branches,
branch,
anytime,
earliest_time,
all_devices,
repo_id,
} = filters;
autosaves
.into_iter()
.filter(move |autosave| {
all_users
|| signature
.name()
.zip(autosave.author.clone())
.is_some_and(|(a, b)| a == b)
|| signature
.email()
.zip(autosave.email.clone())
.is_some_and(|(a, b)| a == b)
})
.filter(move |autosave| all_branches || autosave.branch_name == branch)
.filter(move |autosave| anytime || autosave.time > earliest_time)
.filter(move |autosave| all_devices || autosave.repo_id.as_bytes() != repo_id.as_bytes())
}
pub fn select_autosave(
mut autosaves: Vec<Autosave>,
all_branches: bool,
all_users: bool,
) -> Result<Autosave, inquire::InquireError> {
if autosaves.len() > 1 {
let autosaves = autosaves
.into_iter()
.map(|autosave| {
let device = autosave.host_name.as_ref().unwrap_or(&autosave.repo_id);
let time = chrono::DateTime::from_timestamp(autosave.time.seconds(), 0)
.map(|time| time.with_timezone(&Local))
.map(|time| time.to_rfc2822())
.unwrap_or(autosave.time.seconds().to_string());
let branch = if all_branches {
format!(" on {}", &autosave.branch_name)
} else {
String::new()
};
let author = if let Some(author) =
autosave.author.as_ref().or(autosave.email.as_ref())
&& all_users
{
format!(" by {author}")
} else {
String::new()
};
AutosaveOption {
text: format!("{device} ({time}{branch}{author})"),
value: autosave,
}
})
.collect();
Ok(inquire::Select::new("Select an autosave:", autosaves)
.prompt()?
.value)
} else {
Ok(autosaves
.pop()
.expect("There should be an autosave to select but there isn't. This is a bug!"))
}
}
|