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, filters: AutosaveFilters<'_>, ) -> impl Iterator { 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, all_branches: bool, all_users: bool, ) -> Result { 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!")) } }