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.clear_canvas_notice();
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 let error = error.into();
49 if let Some(save) = self.save.as_mut() {
50 save.status = SaveStatus::Error(error.clone());
51 }
52 self.set_canvas_error(format!("Save failed: {error}"));
53 }
54
55 pub fn complete_save(&mut self, path: &Path) {
56 self.save = None;
57 self.set_canvas_notice(format!("Saved graph to {}", path.display()));
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use clap::Parser;
64
65 use super::{super::App, SaveStatus};
66 use crate::cli::Cli;
67
68 #[test]
69 fn edits_save_state_and_keeps_errors_until_the_next_edit() {
70 let mut app = App::from_cli(Cli::try_parse_from(["cgraph"]).unwrap());
71 app.open_save();
72 app.push_save_char('图');
73 app.push_save_char('.');
74 app.push_save_char('t');
75 app.pop_save_char();
76 assert_eq!(app.save.as_ref().unwrap().input, "图.");
77
78 app.fail_save("target exists");
79 assert_eq!(
80 app.save.as_ref().unwrap().status,
81 SaveStatus::Error("target exists".to_owned())
82 );
83 app.push_save_char('t');
84 assert_eq!(app.save.as_ref().unwrap().status, SaveStatus::Editing);
85 app.close_save();
86 assert!(app.save.is_none());
87 }
88}