libsurfer/
state_file_io.rs
1use std::path::PathBuf;
2
3use color_eyre::eyre::Context;
4
5use crate::{
6 async_util::{perform_async_work, AsyncJob},
7 file_dialog::{load_state_dialog, save_state_dialog},
8 message::Message,
9 SystemState,
10};
11
12impl SystemState {
13 pub fn load_state_file(&mut self, path: Option<PathBuf>) {
14 let sender = self.channels.msg_sender.clone();
15
16 perform_async_work(async move {
17 let source = if let Some(path) = path.clone() {
18 #[cfg(not(target_arch = "wasm32"))]
19 {
20 Some(path.into())
21 }
22 #[cfg(target_arch = "wasm32")]
23 {
24 None
25 }
26 } else {
27 load_state_dialog().await
28 };
29 let Some(source) = source else {
30 return;
31 };
32 let bytes = source.read().await;
33 let new_state = match ron::de::from_bytes(&bytes)
34 .context(format!("Failed loading {}", source.file_name()))
35 {
36 Ok(s) => s,
37 Err(e) => {
38 log::error!("Failed to load state: {e:#?}");
39 return;
40 }
41 };
42 sender.send(Message::LoadState(new_state, path)).unwrap();
43 });
44 }
45
46 pub fn save_state_file(&mut self, path: Option<PathBuf>) {
47 let sender = self.channels.msg_sender.clone();
48 let Some(encoded) = self.encode_state() else {
49 return;
50 };
51
52 perform_async_work(async move {
53 let destination = if let Some(path) = path {
54 #[cfg(not(target_arch = "wasm32"))]
55 {
56 Some(path.into())
57 }
58 #[cfg(target_arch = "wasm32")]
59 {
60 None
61 }
62 } else {
63 save_state_dialog().await
64 };
65 let Some(destination) = destination else {
66 return;
67 };
68
69 #[cfg(not(target_arch = "wasm32"))]
70 sender
71 .send(Message::SetStateFile(destination.path().into()))
72 .unwrap();
73 destination
74 .write(encoded.as_bytes())
75 .await
76 .map_err(|e| log::error!("Failed to write state to {destination:#?} {e:#?}"))
77 .ok();
78 sender
79 .send(Message::AsyncDone(AsyncJob::SaveState))
80 .unwrap();
81 });
82 }
83
84 fn encode_state(&self) -> Option<String> {
85 let opt = ron::Options::default();
86
87 opt.to_string_pretty(&self.user, ron::ser::PrettyConfig::default())
88 .context("Failed to encode state")
89 .map_err(|e| log::error!("Failed to encode state. {e:#?}"))
90 .ok()
91 }
92}