r1 复审的 P1:消息漏斗只解决了「加一支消息」,一组要画真值仍要改 `settings/mod.rs` (`Group.body` 与 `view` 只认 `appearance::State`)。本 commit 补齐与消息漏斗同构的状态漏斗: - 新增 `pages/settings/state.rs`:`Groups`(一个组一个字段,字段类型在组自己文件里)+ `States`(按值传给渲染器的只读视图:外观状态 + 组状态)+ `demo_groups()`(harness 的 `'static` 默认状态)。 - `Group.body` 签名改成 `for<'a> fn(&'a Ui, States<'a>) -> Option<Element>`:每组自己从 `States` 取自己要的数据,「没有可画的状态」返回 `None` 由 `form` 退回演示行。 `appearance` 组照旧接 `pages/appearance/section.rs`(M93 路径行为不变)。 - `App.settings: pages::settings::Groups`(`app/state.rs` 字段列表末尾)+ `app/view.rs` 构造 `States` 走新入口 `pages::page_with_settings`。加/改某一组的字段只改那一组的文件。 - 四个组各自的 `State` 落在各自文件;`java::Message` 留一支只有测试构造的 `Ping`,配 `app/update/settings/tests.rs` 的 `a_group_message_reaches_its_handler_through_the_funnel` ——消息漏斗第一次有**运行时**证据。 r1 其余条目: - P2-1 删掉 `only_the_appearance_group_carries_a_real_control_body`(被四条 per-group 断言蕴含), 并在同处写明删掉之后「唯一性」没人守;三份 section 文档从「改 3 个文件」订正为 2 个。 - P2-2 `pub mod settings` → `pub(crate) mod settings`(四个消息口模块 `pub(crate)`), 并订正两处理由(lint 按类型自身可见性判,不是可达性)。 - P2-3 `pages/mod.rs` 397 行 → 拆出 `pages/message.rs` / `pages/screen.rs`(纯搬移,`pub use` 保证 `pages::Message` / `Action` / `Screen` 路径不变),并删掉 M101 自己那 18 行重复文档。 - P3-1 订正共享点清单(`Key` 由宏从域文件累积生成,加 key 不改 `catalog.rs`)。 - P3-2 守门改成「除已知臂外任何含 `=>` 的行都算兜底」(`other =>` 也拦),并加「恰好四臂」断言。 - P3-3 `ai.rs` → `ai_about.rs` 单独一条 R100 改名提交,`git log --follow` 不断链。 - P3-4 `message.rs` 的「加一支消息改 1 个文件」订正为 2 个。
56 lines
2.8 KiB
Rust
56 lines
2.8 KiB
Rust
//! 设置页分组消息的**二级分发**(M101 `SETTINGSMSG`):
|
||
//! `pages::Message::Settings(GroupMessage)` → 四条填页线各自的 handler。
|
||
//!
|
||
//! ## 为什么分两级
|
||
//!
|
||
//! `app/update/page_messages.rs` 对 [`pages::Message`] 做穷尽匹配(没有 `_ =>`,有
|
||
//! `the_page_match_has_no_wildcard_fallback` 守门)。设置页的四条填页线若各自往 `pages::Message`
|
||
//! 里加变体,就都得改那个文件——四路并行必然冲突。M101 把它们收进一个投递口
|
||
//! `pages::Message::Settings(GroupMessage)`,本文件再把 `GroupMessage` 分给四条线:
|
||
//!
|
||
//! ```text
|
||
//! GroupMessage::Java(m) → settings/java.rs
|
||
//! GroupMessage::Download(m) → settings/download.rs
|
||
//! GroupMessage::LanguageAppearance(m) → settings/language_appearance.rs
|
||
//! GroupMessage::AiAbout(m) → settings/ai_about.rs
|
||
//! ```
|
||
//!
|
||
//! ## 穷尽性:抓得住什么 / 抓不住什么
|
||
//!
|
||
//! - **抓得住**:某条线给 `GroupMessage` 加了载荷变体(= 在自己文件里加了一支消息)却忘了在本
|
||
//! match 里接线 → **E0004**;四个 handler 里对空枚举的 `match message {}` 一旦有人写成
|
||
//! `_ => {}`,`the_group_dispatch_has_no_wildcard_fallback` 会红(兜底会把「漏接线」从编译
|
||
//! 错误降级成「点了没反应」,`page_messages.rs` 的同类守卫是这么写的,这里照抄)。
|
||
//! - **抓不住**:handler 忽略自己的消息(`let _ = message; Task::none()`)、两个 handler 身体写反
|
||
//! 或写成一样——类型对得上就编得过,只有人读能看出来。也因此「接错了组」的一半是编译期兜住的
|
||
//! (载荷类型不同 ⇒ 编不过),另一半(接了个空壳)不是。
|
||
//!
|
||
//! ## 加一支设置页消息要改哪
|
||
//!
|
||
//! 自己那条线的两个文件:消息口(`pages/settings/<线>.rs`)+ 落点(本目录 `<线>.rs`)。
|
||
//! 本文件的 match 只在 `GroupMessage` **加变体**时才动,而那意味着新增一条线,不是加一支消息。
|
||
|
||
use super::*;
|
||
|
||
impl App {
|
||
/// 设置页的分组消息:分给四条线各自的文件,本文件不认识任何一支具体消息。
|
||
pub(super) fn on_settings(&mut self, message: pages::settings::GroupMessage) -> Task<Message> {
|
||
match message {
|
||
pages::settings::GroupMessage::Java(message) => self.on_settings_java(message),
|
||
pages::settings::GroupMessage::Download(message) => self.on_settings_download(message),
|
||
pages::settings::GroupMessage::LanguageAppearance(message) => {
|
||
self.on_settings_language_appearance(message)
|
||
}
|
||
pages::settings::GroupMessage::AiAbout(message) => self.on_settings_ai_about(message),
|
||
}
|
||
}
|
||
}
|
||
|
||
mod ai_about;
|
||
mod download;
|
||
mod java;
|
||
mod language_appearance;
|
||
|
||
#[cfg(test)]
|
||
mod tests;
|