summaryrefslogtreecommitdiff
path: root/systems/_config/src
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2026-03-11 17:38:08 +0800
committer魏曹先生 <1992414357@qq.com>2026-03-11 17:38:08 +0800
commit4effbd209edf96637d7da2b7d29ea1a6de3c637a (patch)
tree397223a02b80b858ceb41af0126d0c9e731f2047 /systems/_config/src
parent794316c6e925097ef6b87693b4a610b4563309e6 (diff)
Add config system and space macro with workspace dependencies
Diffstat (limited to 'systems/_config/src')
-rw-r--r--systems/_config/src/error.rs19
-rw-r--r--systems/_config/src/lib.rs2
-rw-r--r--systems/_config/src/main.rs3
-rw-r--r--systems/_config/src/rw.rs66
4 files changed, 87 insertions, 3 deletions
diff --git a/systems/_config/src/error.rs b/systems/_config/src/error.rs
new file mode 100644
index 0000000..791aab2
--- /dev/null
+++ b/systems/_config/src/error.rs
@@ -0,0 +1,19 @@
+use std::path::PathBuf;
+
+#[derive(thiserror::Error, Debug)]
+pub enum ConfigError {
+ #[error("Failed to read config file: {0}")]
+ ConfigReadFailed(#[source] std::io::Error),
+
+ #[error("Failed to write config file: {0}")]
+ ConfigWriteFailed(#[source] std::io::Error),
+
+ #[error("Config file not found: {0}")]
+ FileNotFound(PathBuf),
+
+ #[error("IO error: {0}")]
+ Io(#[source] std::io::Error),
+
+ #[error("Other error: {0}")]
+ Other(String),
+}
diff --git a/systems/_config/src/lib.rs b/systems/_config/src/lib.rs
new file mode 100644
index 0000000..26fe31a
--- /dev/null
+++ b/systems/_config/src/lib.rs
@@ -0,0 +1,2 @@
+pub mod error;
+pub mod rw;
diff --git a/systems/_config/src/main.rs b/systems/_config/src/main.rs
deleted file mode 100644
index e7a11a9..0000000
--- a/systems/_config/src/main.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
- println!("Hello, world!");
-}
diff --git a/systems/_config/src/rw.rs b/systems/_config/src/rw.rs
new file mode 100644
index 0000000..36ea00c
--- /dev/null
+++ b/systems/_config/src/rw.rs
@@ -0,0 +1,66 @@
+use crate::error::ConfigError;
+use serde::{Deserialize, Serialize};
+use std::path::Path;
+
+pub async fn read_config<C>(path: impl AsRef<Path>) -> Result<C, ConfigError>
+where
+ C: for<'a> Deserialize<'a>,
+{
+ let path_ref = path.as_ref();
+ let ext = path_ref
+ .extension()
+ .and_then(|ext| ext.to_str())
+ .unwrap_or("json");
+ let format = ext_fmt(&ext.to_lowercase());
+
+ let content = std::fs::read_to_string(path_ref).map_err(ConfigError::ConfigReadFailed)?;
+
+ match format {
+ Format::Yaml => {
+ serde_yaml::from_str(&content).map_err(|e| ConfigError::Other(e.to_string()))
+ }
+ Format::Toml => toml::from_str(&content).map_err(|e| ConfigError::Other(e.to_string())),
+ Format::Json => {
+ serde_json::from_str(&content).map_err(|e| ConfigError::Other(e.to_string()))
+ }
+ }
+}
+
+pub async fn write_config<C>(path: impl AsRef<Path>, config: &C) -> Result<(), ConfigError>
+where
+ C: Serialize,
+{
+ let path_ref = path.as_ref();
+ let ext = path_ref
+ .extension()
+ .and_then(|ext| ext.to_str())
+ .unwrap_or("json");
+ let format = ext_fmt(&ext.to_lowercase());
+
+ let content = match format {
+ Format::Yaml => {
+ serde_yaml::to_string(config).map_err(|e| ConfigError::Other(e.to_string()))?
+ }
+ Format::Toml => toml::to_string(config).map_err(|e| ConfigError::Other(e.to_string()))?,
+ Format::Json => {
+ serde_json::to_string_pretty(config).map_err(|e| ConfigError::Other(e.to_string()))?
+ }
+ };
+
+ std::fs::write(path_ref, content).map_err(ConfigError::ConfigWriteFailed)
+}
+
+enum Format {
+ Yaml,
+ Toml,
+ Json,
+}
+
+fn ext_fmt(ext: &str) -> Format {
+ match ext {
+ "yaml" | "yml" => Format::Yaml,
+ "toml" | "tml" => Format::Toml,
+ "json" => Format::Json,
+ _ => Format::Json,
+ }
+}