Refactor saves

This commit is contained in:
traxys 2023-12-09 22:03:51 +01:00
parent 283cf7a4a5
commit e67eb6200b
2 changed files with 49 additions and 36 deletions

View file

@ -1,4 +1,4 @@
use std::{collections::BTreeMap, fs::OpenOptions, num::NonZeroU8, path::PathBuf};
use std::{collections::BTreeMap, num::NonZeroU8};
use iced::{
theme,
@ -10,10 +10,11 @@ use iced::{
};
use iced_aw::{card, modal, number_input, selection_list};
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use crate::{
calc::calc_parser, BoxIter, Config, ContributionPoint, Message, Report, ReportDate, SaveFile,
Spendings, LIST_RULE, SECTION_RULE, TEXT_EMPH1, TEXT_EMPH2, TEXT_H1, TEXT_H2,
calc::calc_parser, BoxIter, Config, ContributionPoint, Message, Report, ReportDate, Spendings,
LIST_RULE, SECTION_RULE, TEXT_EMPH1, TEXT_EMPH2, TEXT_H1, TEXT_H2,
};
struct AddFixed<F> {
@ -778,7 +779,6 @@ pub struct EditState {
recurring: BTreeMap<String, f64>,
variable: BTreeMap<String, (String, Option<f64>)>,
savings: BTreeMap<String, f64>,
save_file: PathBuf,
earnings_1: f64,
earnings_2: f64,
average: NonZeroU8,
@ -850,15 +850,22 @@ macro_rules! msg2 {
};
}
#[derive(Serialize, Deserialize, Default)]
pub(crate) struct EditSaveFile {
#[serde(flatten)]
pub current: Report,
#[serde(default)]
pub archive: BTreeMap<ReportDate, Report>,
}
impl EditState {
pub fn new(save_file: PathBuf) -> Self {
pub fn new() -> Self {
Self {
recurring: Default::default(),
savings: Default::default(),
variable: Default::default(),
earnings_1: Default::default(),
earnings_2: Default::default(),
save_file,
average: NonZeroU8::MIN,
date: None,
}
@ -910,8 +917,8 @@ impl EditState {
}
}
pub(super) fn save(&self, archive: BTreeMap<ReportDate, Report>, pretty: bool) {
let mut save = SaveFile {
pub(super) fn save(&self, archive: BTreeMap<ReportDate, Report>) -> EditSaveFile {
let mut save = EditSaveFile {
current: Default::default(),
archive,
};
@ -923,20 +930,7 @@ impl EditState {
None => save.current = self.report(),
}
let tmp_path = format!(".glaurung-{}", std::process::id());
let save_file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(&tmp_path)
.expect("Can't open temp save file");
let to_writer = match pretty {
true => serde_json::to_writer_pretty,
false => serde_json::to_writer,
};
to_writer(save_file, &save).expect("could not write save file");
std::fs::rename(tmp_path, &self.save_file).expect("could not save data");
save
}
pub(super) fn update(&mut self, message: EditMessage) {

View file

@ -1,6 +1,6 @@
use std::{
collections::BTreeMap,
fs::File,
fs::{File, OpenOptions},
io::BufReader,
num::NonZeroU8,
ops::{Mul, MulAssign, Sub, SubAssign},
@ -11,7 +11,7 @@ use anyhow::anyhow;
use calc::calc_parser;
use compare::Compare;
use directories::ProjectDirs;
use edit::{EditMessage, EditState};
use edit::{EditMessage, EditState, EditSaveFile};
use either::Either;
use iced::{
font, subscription,
@ -203,7 +203,7 @@ pub(crate) trait Spendings {
}
#[derive(Serialize, Deserialize, Clone)]
struct Report {
pub(crate) struct Report {
#[serde(default)]
recurring: BTreeMap<String, f64>,
#[serde(default)]
@ -283,7 +283,7 @@ impl Spendings for (ReportDate, Report) {
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Hash)]
struct ReportDate {
pub(crate) struct ReportDate {
pub year: u64,
pub month: u8,
}
@ -362,9 +362,7 @@ impl<'de> Deserialize<'de> for ReportDate {
#[derive(Serialize, Deserialize, Default)]
struct SaveFile {
#[serde(flatten)]
current: Report,
#[serde(default)]
archive: BTreeMap<ReportDate, Report>,
edit: EditSaveFile,
}
#[derive(Default)]
@ -417,6 +415,8 @@ struct Glaurung {
edit: EditState,
view: CurrentView,
save_file: PathBuf,
compare_left: Option<CompareLoad>,
compare_right: Option<CompareLoad>,
@ -436,6 +436,26 @@ impl Glaurung {
.map(|rep| (e, Box::new((r, rep.clone())) as Box<dyn Spendings>)),
}
}
fn save(&self) {
let edit = self.edit.save(self.archive.clone());
let save = SaveFile { edit };
let tmp_path = format!(".glaurung-{}", std::process::id());
let save_file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open(&tmp_path)
.expect("Can't open temp save file");
let to_writer = match self.config.pretty_save {
true => serde_json::to_writer_pretty,
false => serde_json::to_writer,
};
to_writer(save_file, &save).expect("could not write save file");
std::fs::rename(tmp_path, &self.save_file).expect("could not save data");
}
}
impl Application for Glaurung {
@ -447,14 +467,15 @@ impl Application for Glaurung {
fn new(config: Self::Flags) -> (Self, Command<Message>) {
let mut this = Self {
config: config.config,
edit: EditState::new(config.save_file),
archive: config.save.archive,
edit: EditState::new(),
save_file: config.save_file,
archive: config.save.edit.archive,
view: CurrentView::Edit,
compare_left: None,
compare_right: None,
};
this.edit.load(None, config.save.current);
this.edit.load(None, config.save.edit.current);
(
this,
@ -481,14 +502,12 @@ impl Application for Glaurung {
Message::FontLoaded(r) => r.expect("could not load font"),
Message::Event(ev) => {
if let Event::Window(window::Event::CloseRequested) = ev {
self.edit
.save(self.archive.clone(), self.config.pretty_save);
self.save();
return window::close();
}
}
Message::Load(d) => {
self.edit
.save(self.archive.clone(), self.config.pretty_save);
self.save();
self.edit
.load(Some(d), self.archive.get(&d).cloned().unwrap_or_default());
}