61 lines
1.6 KiB
Rust
61 lines
1.6 KiB
Rust
#![feature(try_blocks)]
|
|
#![feature(drain_filter)]
|
|
|
|
mod app;
|
|
|
|
use tokio::runtime::{Builder, Handle};
|
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
|
use crate::app::{
|
|
State,
|
|
config::Config,
|
|
user_config::UserConfig,
|
|
};
|
|
use std::path::Path;
|
|
use tokio::fs::OpenOptions;
|
|
use futures::FutureExt;
|
|
use std::sync::Arc;
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
let runtime = Builder::new_multi_thread()
|
|
.enable_all()
|
|
.build()?;
|
|
|
|
let handle = runtime.handle().clone();
|
|
runtime.block_on(inner(handle))
|
|
}
|
|
|
|
async fn inner(runtime: Handle) -> anyhow::Result<()> {
|
|
let mut uc_toml = String::new();
|
|
tokio::fs::File::open("config.toml").await?.read_to_string(&mut uc_toml).await?;
|
|
let user_config: UserConfig = toml::from_str(&uc_toml)?;
|
|
|
|
let c_path = Path::new("data.json");
|
|
let config: Config = if c_path.exists() {
|
|
let mut c_json = String::new();
|
|
tokio::fs::File::open(c_path).await?.read_to_string(&mut c_json).await?;
|
|
serde_json::from_str(&c_json)?
|
|
} else {
|
|
Config::default()
|
|
};
|
|
|
|
let state = State::new(runtime, user_config, config).await?;
|
|
save_config(c_path, Arc::clone(&state)).await?;
|
|
|
|
tokio::signal::ctrl_c()
|
|
.then(|_| save_config(c_path, Arc::clone(&state)))
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn save_config(path: &Path, state: Arc<State>) -> anyhow::Result<()> {
|
|
let mut config_file = OpenOptions::new()
|
|
.create(true)
|
|
.write(true)
|
|
.truncate(true)
|
|
.open(path)
|
|
.await?;
|
|
config_file.write_all(&serde_json::to_vec(&*state.config.read().await)?).await?;
|
|
Ok(())
|
|
}
|