Add a state file to persist data
This commit is contained in:
parent
e9058c6b27
commit
066bcb5555
3 changed files with 187 additions and 19 deletions
104
Cargo.lock
generated
104
Cargo.lock
generated
|
|
@ -90,6 +90,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.75"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "approx"
|
name = "approx"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
|
@ -428,6 +434,27 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "directories"
|
||||||
|
version = "5.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"option-ext",
|
||||||
|
"redox_users",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dispatch"
|
name = "dispatch"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
@ -679,9 +706,13 @@ checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945"
|
||||||
name = "glaurung"
|
name = "glaurung"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"directories",
|
||||||
"iced",
|
"iced",
|
||||||
"iced_aw",
|
"iced_aw",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1055,6 +1086,12 @@ dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jni-sys"
|
name = "jni-sys"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|
@ -1137,6 +1174,17 @@ version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libredox"
|
||||||
|
version = "0.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.4.1",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall 0.4.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libredox"
|
name = "libredox"
|
||||||
version = "0.0.2"
|
version = "0.0.2"
|
||||||
|
|
@ -1517,13 +1565,19 @@ version = "1.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "option-ext"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "orbclient"
|
name = "orbclient"
|
||||||
version = "0.3.47"
|
version = "0.3.47"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166"
|
checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libredox",
|
"libredox 0.0.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1857,6 +1911,17 @@ dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"libredox 0.0.1",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "renderdoc-sys"
|
name = "renderdoc-sys"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
|
@ -1892,6 +1957,12 @@ dependencies = [
|
||||||
"unicode-script",
|
"unicode-script",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scoped-tls"
|
name = "scoped-tls"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
|
@ -1917,6 +1988,37 @@ dependencies = [
|
||||||
"tiny-skia 0.8.4",
|
"tiny-skia 0.8.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.192"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.192"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.39",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.108"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simd-adler32"
|
name = "simd-adler32"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,13 @@ authors = ["traxys <quentin@familleboyer.net>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1.0.75"
|
||||||
|
directories = "5.0.1"
|
||||||
iced = { version = "0.10.0", features = ["lazy"] }
|
iced = { version = "0.10.0", features = ["lazy"] }
|
||||||
iced_aw = { version = "0.7.0", default-features = false, features = [
|
iced_aw = { version = "0.7.0", default-features = false, features = [
|
||||||
"modal",
|
"modal",
|
||||||
"card",
|
"card",
|
||||||
] }
|
] }
|
||||||
itertools = "0.11.0"
|
itertools = "0.11.0"
|
||||||
|
serde = { version = "1.0.192", features = ["derive"] }
|
||||||
|
serde_json = "1.0.108"
|
||||||
|
|
|
||||||
98
src/main.rs
98
src/main.rs
|
|
@ -1,25 +1,23 @@
|
||||||
use std::collections::BTreeMap;
|
use std::{
|
||||||
|
collections::BTreeMap,
|
||||||
|
fs::{File, OpenOptions},
|
||||||
|
io::BufReader,
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
use anyhow::anyhow;
|
||||||
|
use directories::ProjectDirs;
|
||||||
use iced::{
|
use iced::{
|
||||||
font,
|
font, subscription,
|
||||||
widget::{button, column, component, horizontal_rule, row, text, text_input},
|
widget::{button, column, component, horizontal_rule, row, text, text_input},
|
||||||
Application, Command, Renderer, Settings, Theme,
|
window, Application, Command, Event, Renderer, Settings, Theme,
|
||||||
};
|
};
|
||||||
use iced_aw::{card, modal};
|
use iced_aw::{card, modal};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
type Element<'a> = iced::Element<'a, Message>;
|
type Element<'a> = iced::Element<'a, Message>;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
enum Message {
|
|
||||||
AddRecurring(String, f64),
|
|
||||||
FontLoaded(Result<(), font::Error>),
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Glaurung {
|
|
||||||
recurring: BTreeMap<String, f64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AddRecurring<F> {
|
struct AddRecurring<F> {
|
||||||
on_submit: F,
|
on_submit: F,
|
||||||
}
|
}
|
||||||
|
|
@ -226,16 +224,45 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
enum Message {
|
||||||
|
Event(Event),
|
||||||
|
AddRecurring(String, f64),
|
||||||
|
FontLoaded(Result<(), font::Error>),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Glaurung {
|
||||||
|
recurring: BTreeMap<String, f64>,
|
||||||
|
save_file: File,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Default)]
|
||||||
|
struct SaveFile {
|
||||||
|
recurring: BTreeMap<String, f64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct AppConfig {
|
||||||
|
save: SaveFile,
|
||||||
|
save_file: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
impl Application for Glaurung {
|
impl Application for Glaurung {
|
||||||
type Message = Message;
|
type Message = Message;
|
||||||
type Theme = Theme;
|
type Theme = Theme;
|
||||||
type Executor = iced::executor::Default;
|
type Executor = iced::executor::Default;
|
||||||
type Flags = ();
|
type Flags = AppConfig;
|
||||||
|
|
||||||
fn new(_flags: Self::Flags) -> (Self, Command<Message>) {
|
fn new(config: Self::Flags) -> (Self, Command<Message>) {
|
||||||
(
|
(
|
||||||
Self {
|
Self {
|
||||||
recurring: BTreeMap::new(),
|
recurring: config.save.recurring,
|
||||||
|
save_file: OpenOptions::new()
|
||||||
|
.create(true)
|
||||||
|
.write(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(config.save_file)
|
||||||
|
.expect("Can't open data file"),
|
||||||
},
|
},
|
||||||
Command::batch(vec![
|
Command::batch(vec![
|
||||||
font::load(iced_aw::graphics::icons::ICON_FONT_BYTES).map(Message::FontLoaded)
|
font::load(iced_aw::graphics::icons::ICON_FONT_BYTES).map(Message::FontLoaded)
|
||||||
|
|
@ -247,12 +274,29 @@ impl Application for Glaurung {
|
||||||
"Glaurung - Account Manager".into()
|
"Glaurung - Account Manager".into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn subscription(&self) -> iced::Subscription<Self::Message> {
|
||||||
|
subscription::events().map(Message::Event)
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&mut self, message: Self::Message) -> Command<Message> {
|
fn update(&mut self, message: Self::Message) -> Command<Message> {
|
||||||
match message {
|
match message {
|
||||||
Message::AddRecurring(name, value) => {
|
Message::AddRecurring(name, value) => {
|
||||||
self.recurring.insert(name, value);
|
self.recurring.insert(name, value);
|
||||||
}
|
}
|
||||||
Message::FontLoaded(r) => r.expect("could not load font"),
|
Message::FontLoaded(r) => r.expect("could not load font"),
|
||||||
|
Message::Event(ev) => {
|
||||||
|
if let Event::Window(window::Event::CloseRequested) = ev {
|
||||||
|
serde_json::to_writer(
|
||||||
|
&mut self.save_file,
|
||||||
|
&SaveFile {
|
||||||
|
recurring: std::mem::take(&mut self.recurring),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("could not write save file");
|
||||||
|
|
||||||
|
return window::close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Command::none()
|
Command::none()
|
||||||
|
|
@ -275,6 +319,24 @@ impl Application for Glaurung {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> iced::Result {
|
fn main() -> anyhow::Result<()> {
|
||||||
Glaurung::run(Settings::default())
|
let project_dir = ProjectDirs::from("net", "traxys", "glaurung").ok_or(anyhow!(""))?;
|
||||||
|
let state_dir = project_dir
|
||||||
|
.state_dir()
|
||||||
|
.ok_or(anyhow!("No state directory"))?;
|
||||||
|
std::fs::create_dir_all(state_dir)?;
|
||||||
|
|
||||||
|
let save_file = state_dir.join("data.json");
|
||||||
|
|
||||||
|
let save = match save_file.exists() {
|
||||||
|
false => Default::default(),
|
||||||
|
true => serde_json::from_reader(BufReader::new(File::open(&save_file)?))?,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut settings = Settings::with_flags(AppConfig { save, save_file });
|
||||||
|
settings.exit_on_close_request = false;
|
||||||
|
|
||||||
|
Glaurung::run(settings)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue