radar-g/radarg_core/src/config.rs
2024-09-13 09:53:17 +08:00

125 lines
3.2 KiB
Rust

use crate::errors::ConfigError;
use crate::radarg_data::ProbeDataType;
use crate::utils::color_tools::hex_to_rgba_u8;
use crate::Asset;
use dirs;
use num_traits::{AsPrimitive, FromPrimitive};
use serde::{Deserialize, Serialize};
use std::env;
use toml;
macro_rules! find_cmap {
($c:ident,$find_on:ident,$({$b:tt => $name:literal}),*) => {
{
let mut cmap = None;
match $c {
$(
$b => {
let find_v = $find_on.iter().find(|cb| cb.type_name == $name).map(|cb| cb);
cmap = find_v;
}
)*
_ => {}
}
cmap
}
};
}
#[derive(Deserialize, Serialize)]
pub struct Setting {
pub cmap: Vec<CB>,
}
impl Setting {
pub fn new() -> Self {
use std::fs::read_to_string;
use std::io::*;
let current_dir = env::current_dir().unwrap();
if !current_dir.join("config.toml").exists() {
let default_config = Asset::get("config.toml").unwrap();
let folder_path = current_dir.clone();
let conf = folder_path.join("config.toml");
let mut file = std::fs::File::create_new(&conf).unwrap();
file.write_all(&default_config.data).unwrap();
}
let file = read_to_string(current_dir.join("config.toml")).unwrap();
let setting: Setting = toml::from_str(&file).unwrap();
setting
}
pub fn find(&self, name: &ProbeDataType) -> Option<&CB> {
let cmap = &self.cmap;
use ProbeDataType::*;
find_cmap!(
name, cmap,
{DBZ => "DBZ"},
{V => "VEL"},
{VIL => "VIL"},
{CC => "CC"},
{KDP => "KDP"},
{ZDR => "ZDR"},
{PHIDP => "PHIDP"}
)
}
}
#[derive(Deserialize, Serialize)]
pub struct CB {
#[serde(rename = "type")]
pub type_name: String,
pub colors: Vec<String>,
pub levels: Vec<f32>,
}
impl CB {
pub fn value_range(&self) -> [f32; 2] {
let mut range = [0.0, 0.0];
let levels = &self.levels;
range[0] = levels[0];
range[1] = levels[levels.len() - 1];
range
}
pub fn color(&self) -> Result<Vec<[u8; 4]>, ConfigError> {
if self.colors.len() != self.levels.len() - 1 {
return Err(ConfigError::FormatError(
"The number of colors and levels are not matched".to_string(),
));
}
let mut result = self
.colors
.iter()
.map(|v| hex_to_rgba_u8(v))
.collect::<std::result::Result<Vec<_>, String>>()
.map_err(|v| ConfigError::FormatError(v.to_string()))?;
let mut span = Vec::with_capacity(self.levels.len() - 1);
for idx in 0..self.levels.len() - 1 {
let start = self.levels[idx];
let end = self.levels[idx + 1];
let range = end - start;
span.push(range);
}
let range = self.value_range();
let all_range = range[1] - range[0];
for (level, r) in span.iter().zip(result.iter_mut()) {
r[3] = ((*level / all_range) * 255.0) as u8;
}
Ok(result)
}
}