1use std::path::Path;
2
3use serde::{Deserialize, Serialize};
4
5use crate::app::App;
6use crate::engine::EngineKind;
7
8#[derive(Serialize, Deserialize)]
9pub struct Workspace {
10 pub pattern: String,
11 pub test_string: String,
12 pub replacement: String,
13 pub engine: String,
14 pub case_insensitive: bool,
15 pub multiline: bool,
16 pub dotall: bool,
17 pub unicode: bool,
18 pub extended: bool,
19 pub show_whitespace: bool,
20}
21
22impl Workspace {
23 pub fn from_app(app: &App) -> Self {
24 let engine = match app.engine_kind {
25 EngineKind::RustRegex => "rust",
26 EngineKind::FancyRegex => "fancy",
27 #[cfg(feature = "pcre2-engine")]
28 EngineKind::Pcre2 => "pcre2",
29 };
30 Self {
31 pattern: app.regex_editor.content().to_string(),
32 test_string: app.test_editor.content().to_string(),
33 replacement: app.replace_editor.content().to_string(),
34 engine: engine.to_string(),
35 case_insensitive: app.flags.case_insensitive,
36 multiline: app.flags.multi_line,
37 dotall: app.flags.dot_matches_newline,
38 unicode: app.flags.unicode,
39 extended: app.flags.extended,
40 show_whitespace: app.show_whitespace,
41 }
42 }
43
44 pub fn apply(&self, app: &mut App) {
45 let engine_kind = match self.engine.as_str() {
46 "fancy" => EngineKind::FancyRegex,
47 #[cfg(feature = "pcre2-engine")]
48 "pcre2" => EngineKind::Pcre2,
49 _ => EngineKind::RustRegex,
50 };
51 if app.engine_kind != engine_kind {
52 app.engine_kind = engine_kind;
53 app.switch_engine_to(engine_kind);
54 }
55 app.flags.case_insensitive = self.case_insensitive;
56 app.flags.multi_line = self.multiline;
57 app.flags.dot_matches_newline = self.dotall;
58 app.flags.unicode = self.unicode;
59 app.flags.extended = self.extended;
60 app.show_whitespace = self.show_whitespace;
61 app.set_test_string(&self.test_string);
62 if !self.replacement.is_empty() {
63 app.set_replacement(&self.replacement);
64 }
65 app.set_pattern(&self.pattern);
66 }
67
68 pub fn save(&self, path: &Path) -> anyhow::Result<()> {
69 let content = toml::to_string_pretty(self)?;
70 std::fs::write(path, content)?;
71 Ok(())
72 }
73
74 pub fn load(path: &Path) -> anyhow::Result<Self> {
75 let content = std::fs::read_to_string(path)?;
76 let ws: Self = toml::from_str(&content)?;
77 Ok(ws)
78 }
79}