feat(picker): save and read configuration on disk. #2.
This commit is contained in:
parent
a6e91dfae1
commit
1c38fd970e
10
src-tauri/Cargo.lock
generated
10
src-tauri/Cargo.lock
generated
@ -584,6 +584,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"test_dir",
|
||||
"time",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@ -3165,6 +3166,15 @@ dependencies = [
|
||||
"utf-8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test_dir"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fc19daf9fc57fadcf740c4abaaa0cd08d9ce22a2a0629aaf6cbd9ae4b80683a"
|
||||
dependencies = [
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thin-slice"
|
||||
version = "0.1.1"
|
||||
|
@ -41,3 +41,6 @@ default = [ "custom-protocol" ]
|
||||
# this feature is used used for production builds where `devPath` points to the filesystem
|
||||
# DO NOT remove this
|
||||
custom-protocol = [ "tauri/custom-protocol" ]
|
||||
|
||||
[dev-dependencies]
|
||||
test_dir = "0.2.0"
|
||||
|
@ -1,11 +1,13 @@
|
||||
#[derive(Clone, Copy)]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Copy, Serialize, Deserialize)]
|
||||
pub struct LedStripConfig {
|
||||
pub index: usize,
|
||||
pub global_start_position: usize,
|
||||
pub global_end_position: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Serialize, Deserialize)]
|
||||
pub struct DisplayConfig {
|
||||
pub index_of_display: usize,
|
||||
pub display_width: usize,
|
||||
@ -16,17 +18,6 @@ pub struct DisplayConfig {
|
||||
pub right_led_strip: LedStripConfig,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum LedFlowX {
|
||||
LR, // from left to right
|
||||
RL, // from right to left
|
||||
}
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum LedFlowY {
|
||||
TB, // from top to bottom
|
||||
BT, // from bottom to top
|
||||
}
|
||||
|
||||
impl DisplayConfig {
|
||||
pub fn default(index_of_display: usize, display_width: usize, display_height: usize) -> Self {
|
||||
Self {
|
122
src-tauri/src/picker/config/manger.rs
Normal file
122
src-tauri/src/picker/config/manger.rs
Normal file
@ -0,0 +1,122 @@
|
||||
use std::{
|
||||
env::current_dir,
|
||||
fs::{self, File},
|
||||
io::Read,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tauri::api::path::config_dir;
|
||||
|
||||
use super::DisplayConfig;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct Configuration {
|
||||
config_version: u8,
|
||||
display_configs: Vec<DisplayConfig>,
|
||||
}
|
||||
|
||||
impl Configuration {
|
||||
pub fn default() -> Self {
|
||||
Self {
|
||||
config_version: 1,
|
||||
display_configs: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Manager {
|
||||
config: Configuration,
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
pub fn global() -> &'static Manager {
|
||||
static DISPLAY_CONFIG_MANAGE: OnceCell<Manager> = OnceCell::new();
|
||||
|
||||
DISPLAY_CONFIG_MANAGE.get_or_init(|| Self::init_from_disk())
|
||||
}
|
||||
|
||||
pub fn default() -> Self {
|
||||
Self::new(Configuration::default())
|
||||
}
|
||||
|
||||
pub fn new(config: Configuration) -> Self {
|
||||
Self { config }
|
||||
}
|
||||
|
||||
pub fn get_config_file_path() -> PathBuf {
|
||||
config_dir()
|
||||
.unwrap_or(current_dir().unwrap())
|
||||
.join("display_config.json")
|
||||
}
|
||||
|
||||
pub fn init_from_disk() -> Self {
|
||||
let config_file_path = Self::get_config_file_path();
|
||||
match Self::read_config_from_disk(config_file_path) {
|
||||
Ok(config) => Self::new(config),
|
||||
Err(_) => Self::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_config_from_disk(config_file_path: PathBuf) -> anyhow::Result<Configuration> {
|
||||
let mut file = File::open(config_file_path)
|
||||
.map_err(|error| anyhow::anyhow!("config file is not existed. {}", error))?;
|
||||
let mut contents = String::new();
|
||||
file.read_to_string(&mut contents)
|
||||
.map_err(|error| anyhow::anyhow!("can not read config file. {}", error))?;
|
||||
serde_json::from_str(&contents)
|
||||
.map_err(|error| anyhow::anyhow!("can not parse config file contents. {}", error))
|
||||
}
|
||||
|
||||
pub fn write_config_to_disk(&self, config_file_path: PathBuf) -> anyhow::Result<()> {
|
||||
let contents = serde_json::to_string(&self.config)
|
||||
.map_err(|error| anyhow::anyhow!("can not serialize config. {}", error))?;
|
||||
fs::write(config_file_path, contents.as_bytes())
|
||||
.map_err(|error| anyhow::anyhow!("can not write config file. {}", error))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use std::fs;
|
||||
|
||||
use serde_json::json;
|
||||
use test_dir::{DirBuilder, TestDir};
|
||||
|
||||
use crate::picker::config::Configuration;
|
||||
|
||||
#[test]
|
||||
fn write_config_to_disk_should_be_successful() {
|
||||
let temp = TestDir::temp().create("config_dir", test_dir::FileType::Dir);
|
||||
let config_file_path = temp.path("config_dir").join("picker.config.json");
|
||||
let manager = crate::picker::config::manger::Manager::default();
|
||||
manager
|
||||
.write_config_to_disk(config_file_path.clone())
|
||||
.unwrap();
|
||||
|
||||
let contents = fs::read_to_string(config_file_path.clone()).unwrap();
|
||||
let _config: Configuration = serde_json::from_str(contents.as_str()).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_config_to_disk_should_be_successful() {
|
||||
let temp = TestDir::temp().create("config_dir", test_dir::FileType::Dir);
|
||||
let config_file_path = temp.path("config_dir").join("picker.config.json");
|
||||
fs::write(
|
||||
config_file_path.clone(),
|
||||
json!({
|
||||
"config_version": 1,
|
||||
"display_configs": []
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes(),
|
||||
).unwrap();
|
||||
let _manager =
|
||||
crate::picker::config::manger::Manager::read_config_from_disk(config_file_path.clone())
|
||||
.unwrap();
|
||||
}
|
||||
}
|
5
src-tauri/src/picker/config/mod.rs
Normal file
5
src-tauri/src/picker/config/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
mod display_config;
|
||||
mod manger;
|
||||
|
||||
pub use display_config::*;
|
||||
pub use manger::*;
|
@ -5,10 +5,7 @@ use scrap::Display;
|
||||
use std::sync::Arc;
|
||||
use tokio::{sync::Mutex, task};
|
||||
|
||||
use crate::picker::{
|
||||
config::{LedFlowX, LedFlowY, LedStripConfig},
|
||||
screen::Screen,
|
||||
};
|
||||
use crate::picker::{config::LedStripConfig, screen::Screen};
|
||||
|
||||
use super::{
|
||||
config::DisplayConfig, display_picker::DisplayPicker, led_color::LedColor,
|
||||
|
Loading…
Reference in New Issue
Block a user