Files
unshell/unshell-server/src/config/mod.rs
T

117 lines
2.8 KiB
Rust
Raw Normal View History

mod blob;
2025-12-17 10:20:50 -07:00
use std::{
collections::HashMap,
error::Error,
fs,
path::{Path, PathBuf},
};
2025-12-16 22:23:54 -07:00
2025-12-17 10:38:37 -07:00
use unshell_lib::{debug, info};
2025-12-17 10:20:50 -07:00
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
2025-12-17 10:38:37 -07:00
struct ComponentMetadata {
2025-12-17 10:20:50 -07:00
name: String,
description: Option<String>,
version: Option<String>,
authors: Option<Vec<String>>,
// Struct to contain build information
2025-12-17 10:38:37 -07:00
#[serde(default)]
2025-12-17 10:20:50 -07:00
build_config: BuildConfig,
// Other components that can be pointed to by this component
#[serde(default)]
child_components: Vec<PathBuf>,
}
2025-12-17 10:38:37 -07:00
#[derive(Default, Debug, Clone, serde::Deserialize, serde::Serialize)]
2025-12-17 10:20:50 -07:00
struct BuildConfig {
// Cargo feature list of a component
// (Name, Description)
#[serde(default)]
features: HashMap<String, String>,
}
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
2025-12-17 16:40:34 -07:00
pub enum ConfigStructField {
2025-12-17 10:20:50 -07:00
Header(String),
Text(String),
String {
// Default value of string edit in struct
#[serde(default)]
default: String,
max_length: Option<usize>,
// Display string edit as password
#[serde(default)]
protected: Option<bool>,
},
Integer {
// Default value of integer in struct
#[serde(default)]
default: i32,
min: Option<i32>,
max: Option<i32>,
},
// Checkbox
// Dropdown
// Collapsing header
// Slider
// ...
}
2025-12-17 10:38:37 -07:00
#[derive(Clone, Debug)]
pub struct ComponentState {
metadata: ComponentMetadata,
path: PathBuf,
}
pub fn load_config(path: &PathBuf) -> Result<Vec<ComponentState>, Box<dyn Error>> {
2025-12-17 10:20:50 -07:00
let path_absolute = fs::canonicalize(path.clone())?;
debug!("Loading data from path: `{:?}`", path_absolute);
2025-12-17 10:20:50 -07:00
// Read string as path
let config_str = fs::read_to_string(path.clone())?;
// Load config from String
let config = toml::from_str::<ComponentMetadata>(&config_str)?;
2025-12-17 10:38:37 -07:00
info!("Loaded component `{}`", config.name);
let parent_path = path_absolute.parent().expect("Path must have parent");
2025-12-17 10:20:50 -07:00
if config.child_components.is_empty() {
2025-12-17 10:38:37 -07:00
Ok(vec![ComponentState {
metadata: config,
path: PathBuf::from(parent_path),
}])
2025-12-17 10:20:50 -07:00
} else {
let mut config_vec = vec![];
// Load each child component
for component_path in &config.child_components {
let path = Path::join(parent_path, component_path);
let mut config = load_config(&path)?;
config_vec.append(&mut config);
}
2025-12-17 10:38:37 -07:00
config_vec.insert(
0,
ComponentState {
metadata: config,
path: PathBuf::from(parent_path),
},
);
2025-12-17 10:20:50 -07:00
Ok(config_vec)
}
}
// pub fn parse_toml() -> ComponentMetadata {
// let data = include_str!("../../test.toml");
// let config = toml::from_str(data).unwrap();
// config
// }