use std::path::{Path, PathBuf};
use badterm_core::screen::Screen;
use super::files::{FilePicker, PickerAction};
use crate::input::{Key, Mods};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SaveFormat {
Ansi,
Text,
Png,
}
impl SaveFormat {
pub fn from_path(path: &Path) -> Option<SaveFormat> {
match path.extension()?.to_str()?.to_ascii_lowercase().as_str() {
"ans" | "ansi" => Some(SaveFormat::Ansi),
"txt" | "asc" => Some(SaveFormat::Text),
"png" => Some(SaveFormat::Png),
_ => None,
}
}
}
pub enum SaveAction {
None,
Cancel,
Save(PathBuf),
}
pub struct SavePrompt {
picker: FilePicker,
}
impl SavePrompt {
pub fn new(default: &Path) -> SavePrompt {
SavePrompt { picker: FilePicker::save(default, &[".ans", ".ansi", ".txt", ".asc", ".png"]) }
}
pub fn handle_key(&mut self, key: Key, mods: Mods) -> SaveAction {
if key == Key::Escape && !self.picker.is_typing() {
return SaveAction::Cancel;
}
match self.picker.handle_key(key, mods) {
PickerAction::Chosen(paths) => SaveAction::Save(paths[0].clone()),
PickerAction::None => SaveAction::None,
}
}
pub fn draw(&mut self, s: &mut Screen) -> Option<(usize, usize)> {
let note = ".ans or .txt: the scrollback and screen, .png: the screen as it is";
self.picker.window(s, "Save Scrollback", note, "save")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn save_where_browsed_to() {
let dir = std::env::temp_dir().join(format!("badterm-save-{}", std::process::id()));
std::fs::create_dir_all(dir.join("art")).unwrap();
let mut p = SavePrompt::new(&dir.join("vortex.ans"));
let mut s = Screen::new(80, 25, 0);
assert!(p.draw(&mut s).is_some(), "the name has the cursor");
p.handle_key(Key::Tab, Mods::default());
p.handle_key(Key::Char('a'), Mods::default());
p.handle_key(Key::Enter, Mods::default());
p.handle_key(Key::Tab, Mods::default());
match p.handle_key(Key::Enter, Mods::default()) {
SaveAction::Save(path) => assert_eq!(path, dir.join("art").join("vortex.ans")),
_ => panic!(),
}
assert!(matches!(p.handle_key(Key::Escape, Mods::default()), SaveAction::Cancel));
std::fs::remove_dir_all(&dir).unwrap();
}
#[test]
fn format_follows_the_extension() {
assert_eq!(SaveFormat::from_path(Path::new("a/b.ANS")), Some(SaveFormat::Ansi));
assert_eq!(SaveFormat::from_path(Path::new("b.txt")), Some(SaveFormat::Text));
assert_eq!(SaveFormat::from_path(Path::new("b.png")), Some(SaveFormat::Png));
assert_eq!(SaveFormat::from_path(Path::new("b")), None);
}
}