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",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build",
|
"tauri-build",
|
||||||
|
"test_dir",
|
||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
@ -3165,6 +3166,15 @@ dependencies = [
|
|||||||
"utf-8",
|
"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]]
|
[[package]]
|
||||||
name = "thin-slice"
|
name = "thin-slice"
|
||||||
version = "0.1.1"
|
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
|
# this feature is used used for production builds where `devPath` points to the filesystem
|
||||||
# DO NOT remove this
|
# DO NOT remove this
|
||||||
custom-protocol = [ "tauri/custom-protocol" ]
|
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 struct LedStripConfig {
|
||||||
pub index: usize,
|
pub index: usize,
|
||||||
pub global_start_position: usize,
|
pub global_start_position: usize,
|
||||||
pub global_end_position: usize,
|
pub global_end_position: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, Serialize, Deserialize)]
|
||||||
pub struct DisplayConfig {
|
pub struct DisplayConfig {
|
||||||
pub index_of_display: usize,
|
pub index_of_display: usize,
|
||||||
pub display_width: usize,
|
pub display_width: usize,
|
||||||
@ -16,17 +18,6 @@ pub struct DisplayConfig {
|
|||||||
pub right_led_strip: LedStripConfig,
|
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 {
|
impl DisplayConfig {
|
||||||
pub fn default(index_of_display: usize, display_width: usize, display_height: usize) -> Self {
|
pub fn default(index_of_display: usize, display_width: usize, display_height: usize) -> Self {
|
||||||
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 std::sync::Arc;
|
||||||
use tokio::{sync::Mutex, task};
|
use tokio::{sync::Mutex, task};
|
||||||
|
|
||||||
use crate::picker::{
|
use crate::picker::{config::LedStripConfig, screen::Screen};
|
||||||
config::{LedFlowX, LedFlowY, LedStripConfig},
|
|
||||||
screen::Screen,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
config::DisplayConfig, display_picker::DisplayPicker, led_color::LedColor,
|
config::DisplayConfig, display_picker::DisplayPicker, led_color::LedColor,
|
||||||
|
Loading…
Reference in New Issue
Block a user