138 lines
3.5 KiB
Rust
138 lines
3.5 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, path::PathBuf};
|
|
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 common: Common,
|
|
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)
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize)]
|
|
pub struct Common {
|
|
pub background: BackgroundType,
|
|
pub path: PathBuf,
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize, Debug)]
|
|
pub enum BackgroundType {
|
|
Terrain,
|
|
Earth,
|
|
}
|