1use std::path::Path;
2
3use super::App;
4
5#[derive(Clone, Debug, Eq, PartialEq)]
6pub enum SaveStatus {
7 Editing,
8 Error(String),
9}
10
11#[derive(Clone, Debug, Eq, PartialEq)]
12pub struct SaveState {
13 pub input: String,
14 pub status: SaveStatus,
15}
16
17impl App {
18 pub fn open_save(&mut self) {
19 self.pending_key = None;
20 self.canvas_notice = None;
21 self.save = Some(SaveState {
22 input: String::new(),
23 status: SaveStatus::Editing,
24 });
25 }
26
27 pub fn close_save(&mut self) {
28 self.save = None;
29 }
30
31 pub fn push_save_char(&mut self, character: char) {
32 let Some(save) = self.save.as_mut() else {
33 return;
34 };
35 save.input.push(character);
36 save.status = SaveStatus::Editing;
37 }
38
39 pub fn pop_save_char(&mut self) {
40 let Some(save) = self.save.as_mut() else {
41 return;
42 };
43 save.input.pop();
44 save.status = SaveStatus::Editing;
45 }
46
47 pub fn fail_save(&mut self, error: impl Into<String>) {
48 if let Some(save) = self.save.as_mut() {
49 save.status = SaveStatus::Error(error.into());
50 }
51 }
52
53 pub fn complete_save(&mut self, path: &Path) {
54 self.save = None;
55 self.canvas_notice = Some(format!("Saved graph to {}", path.display()));
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use clap::Parser;
62
63 use super::{super::App, SaveStatus};
64 use crate::cli::Cli;
65
66 #[test]
67 fn edits_save_state_and_keeps_errors_until_the_next_edit() {
68 let mut app = App::from_cli(Cli::try_parse_from(["cgraph"]).unwrap());
69 app.open_save();
70 app.push_save_char('图');
71 app.push_save_char('.');
72 app.push_save_char('t');
73 app.pop_save_char();
74 assert_eq!(app.save.as_ref().unwrap().input, "图.");
75
76 app.fail_save("target exists");
77 assert_eq!(
78 app.save.as_ref().unwrap().status,
79 SaveStatus::Error("target exists".to_owned())
80 );
81 app.push_save_char('t');
82 assert_eq!(app.save.as_ref().unwrap().status, SaveStatus::Editing);
83 app.close_save();
84 assert!(app.save.is_none());
85 }
86}