feat(storage): Phase 5 C1 — AppConfig 持久化到 config.json
- src/storage/config.rs: AppConfig + ServerEntry + load_config +
save_config,atomic write(tmp + rename + fsync);多 server
数据结构按 §21 落地但 V1 只 active 一个;3 个 #[cfg(test)]
round-trip + default + missing-field 测试
- src/storage/state.rs: 从 src/storage.rs 拆过来;atomic write + 2
个测试(default 960×680 + JSON round-trip)
- src/storage/mod.rs: pub use re-export 两组 API
- src/config.rs: 重构为 ActiveConfig thin wrapper,调
storage::load_config() 拿到第一个 selected_server;placeholder
hardcoded URL/token 在 §19/§20 意义上不再合适,删掉
- src/gotify/model.rs: ServerConfig 加 Serialize/Deserialize(要
写到 config.json 必须能 serialize;token 仍走 §20 不进日志)
- src/lib.rs: run() 启动用 ActiveConfig::load() 取代 placeholder;
on_test_connection_requested 同样改用 ActiveConfig::load()
- 删除 src/storage.rs(被 src/storage/{config,state}.rs 替代;
同样内容已迁过去)
避坑:
- ServerConfig 之前没 derive Serialize,所以 #[serde(flatten)]
嵌套到 ServerEntry 失败——加 derive 是必要的
- src/storage.rs 和 src/storage/mod.rs 不能并存,否则 Rust 报
ambiguous module;删旧文件就行
- AppConfig 多 vec + serde default 让旧 config 文件(字段缺失)
也能 forward-compat parse(3 个测试覆盖)
验证:cargo build / build --release 都 exit 0,0 warning
- cargo test: 14 passed (5 storage unit + 6 api + 3 websocket); 0 failed
- debug 35.54 MB, subsystem = WINDOWS_CUI
- release 9.76 MB, subsystem = WINDOWS_GUI
This commit is contained in:
+4
-4
@@ -1,7 +1,7 @@
|
||||
//! Windows Gotify Client (Rust) — core library.
|
||||
//!
|
||||
//! Phase 4 surface:
|
||||
//! - [`config`]: placeholder AppConfig (Phase 5 swaps for persistence)
|
||||
//! - [`config`]: active-config wrapper (Phase 5 C1: reads storage)
|
||||
//! - [`error`]: AppError / AppResult
|
||||
//! - [`gotify`]: blocking REST + WebSocket clients (Phase 3/4)
|
||||
//! - [`logging`]: tracing-subscriber init
|
||||
@@ -58,8 +58,8 @@ pub fn run() -> error::AppResult<()> {
|
||||
initial_state.last_window_height.max(0) as f32,
|
||||
)));
|
||||
|
||||
// ── Phase 3 C2 + 4 C2: HTTP catch-up, then channel for WS ────
|
||||
let cfg = config::AppConfig::placeholder();
|
||||
// ── Phase 3 C2 + 4 C2 + 5 C1: HTTP catch-up, then channel for WS ────
|
||||
let cfg = config::ActiveConfig::load()?;
|
||||
let shared_model: Rc<VecModel<MessageItem>>;
|
||||
let status_text: String;
|
||||
let is_connected: bool;
|
||||
@@ -163,7 +163,7 @@ pub fn run() -> error::AppResult<()> {
|
||||
let ui_handle = ui.as_weak();
|
||||
move || {
|
||||
tracing::info!("settings: Test Connection clicked");
|
||||
let Some(server) = config::AppConfig::placeholder().server else {
|
||||
let Some(server) = config::ActiveConfig::load().ok().and_then(|c| c.server) else {
|
||||
return;
|
||||
};
|
||||
match models::try_fetch_initial_data(&server.base_url, &server.token) {
|
||||
|
||||
Reference in New Issue
Block a user