refactor: 清理死代码与冗余,修复 mhchem 模块的 clippy 阻断

mhchem 机械移植引入了一个 deny-by-default 的 useless_attribute 硬错误
(mhchem_tables.rs 顶部的 outer #[allow] 挂在 use 语句上),导致
make lint / CI check job 失败。顺带清理同模块的死代码与风格项,以及仓库
内其他确认无引用的死代码。

- mhchem_tables.rs: 删除无效 outer allow、未使用的 `use super::*`、
  pq_action 未用形参 buf→_buf;v.get(0)→v.first()
- mhchem.rs: 删除从未调用的 Field::empty;修正 &*RE→&RE、Default 字段
  重赋值;Parsed/Out 加 large_enum_variant allow(镜像上游结构,
  经 Vec 进堆,非栈热路径)
- codemirror_bridge.rs: 删除 SqlSchema/SqlTable 上过期的 dead_code
  allow——get_db_schema 早已消费这两个类型
- ssr_cache.rs: 删除生产路径从未调用的 invalidate_ssr_home(首页已由
  invalidate_ssr_all_public 覆盖),修正相关注释与测试
- auth.rs: 删除预留给未实现用户管理功能的 invalidate_user_sessions

验证:cargo clippy --all-targets --all-features -- -D warnings 通过;
mhchem/ssr_cache 共 20 项测试通过。
This commit is contained in:
xfy 2026-07-23 13:32:46 +08:00
parent 6276bab6c6
commit 17d596c512
5 changed files with 16 additions and 62 deletions

View File

@ -417,26 +417,6 @@ pub async fn get_user_by_token(token: &str) -> Result<Option<SessionUser>, Serve
Ok(user)
}
#[cfg(feature = "server")]
/// 使指定用户的所有 session 立即失效bump `session_generation`。
///
/// 用于角色降级、封禁、密码修改等场景。bump 后该用户所有已签发 session 在下次
/// `get_user_by_token` 时因世代不匹配被逐出缓存并视为未登录。内存缓存无需主动清,
/// 惰性逐出即可。当前仓库无运行时角色变更入口,本函数是为未来「用户管理」功能
/// 预备的基础设施,一旦引入降级/封禁的 server function必须在 UPDATE 后调用。
#[allow(dead_code)] // 预留给未来的用户管理功能(角色变更/封禁触发全量 session 失效)
pub async fn invalidate_user_sessions(user_id: i32) -> Result<(), ServerFnError> {
let client = get_conn().await.map_err(AppError::db_conn)?;
client
.execute(
"UPDATE users SET session_generation = session_generation + 1 WHERE id = $1",
&[&user_id],
)
.await
.map_err(AppError::query)?;
Ok(())
}
/// 获取当前登录用户的公开信息。
///
/// Dioxus server function注册在 `/api` 路径下。

View File

@ -51,16 +51,8 @@ enum Field {
Nodes(Vec<Parsed>),
}
impl Field {
fn empty(&self) -> bool {
match self {
Field::Str(s) => s.is_empty(),
Field::Nodes(v) => v.is_empty(),
}
}
}
/// 解析中间表示:字面字符串或节点。
#[allow(clippy::large_enum_variant)] // 机械移植:镜像 mhchemParser 上游结构Parsed 经 Vec 进堆,非栈热路径
#[derive(Clone, Debug)]
enum Parsed {
S(String),
@ -398,11 +390,11 @@ fn match_pattern(name: &str, input: &str) -> Option<MMatch> {
"x" => re_match(re!("^x")),
"x$" => re_match(re!("^x$")),
"i$" => re_match(re!("^i$")),
"letters" => re_match(&*LETTERS_RE),
"\\greek" => re_match(&*GREEK_RE),
"letters" => re_match(&LETTERS_RE),
"\\greek" => re_match(&GREEK_RE),
"one lowercase latin letter $" => re_match(re!("^(?:([a-z])(?:$|[^a-zA-Z]))$")),
"$one lowercase latin letter$ $" => re_match(re!("^\\$(?:([a-z])(?:$|[^a-zA-Z]))\\$$")),
"one lowercase greek letter $" => re_match(&*ONE_GREEK_RE),
"one lowercase greek letter $" => re_match(&ONE_GREEK_RE),
"digits" => re_match(re!("^[0-9]+")),
"-9.,9" => re_match(re!("^[+\\-]?(?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\\.[0-9]+))")),
"-9.,9 no missing 0" => re_match(re!("^[+\\-]?[0-9]+(?:[.,][0-9]+)?")),
@ -596,6 +588,7 @@ fn mval_str(m: &MVal) -> String {
// 状态机主循环(对应 `_mhchemParser.go`
// =========================================================================
#[allow(clippy::large_enum_variant)] // 同上Out 为动作返回值,瞬态使用
enum Out {
None,
One(Parsed),
@ -622,8 +615,10 @@ fn go(input: &str, machine: &str) -> Vec<Parsed> {
let transitions = transitions_for(machine);
let mut state = String::from("0");
let mut buffer = Buffer::default();
buffer.parenthesis_level = 0;
let mut buffer = Buffer {
parenthesis_level: 0,
..Default::default()
};
let mut output: Vec<Parsed> = Vec::new();
let mut last_input: Option<String> = None;
let mut watchdog = 10i32;
@ -753,7 +748,7 @@ fn generic_action(buf: &mut Buffer, m: &MVal, opt: &Option<String>, type_: &str)
if let (Some(a), MVal::V(v)) = (opt, m) {
Out::One(Parsed::N(NodeData {
type_: a.clone(),
p1: Some(Field::Str(v.get(0).cloned().unwrap_or_default())),
p1: Some(Field::Str(v.first().cloned().unwrap_or_default())),
p2: Some(Field::Str(v.get(1).cloned().unwrap_or_default())),
..Default::default()
}))

View File

@ -2,10 +2,6 @@
// 数据机械移植自 mhchemParser 4.2.2 的 `stateMachines`。
// (被 include 进 mhchem.rs 中部,故不能用 `//!` 内部文档注释。)
#[allow(clippy::needless_pass_by_value)]
use super::*;
// ── Task 构造器 ──────────────────────────────────────────────────────────
fn task(acts: &[(&str, Option<&str>)], next: Option<&str>, revisit: bool, cont: bool) -> Task {
@ -1220,7 +1216,7 @@ fn text_action(buf: &mut Buffer, type_: &str) -> Option<Out> {
}
}
fn pq_action(buf: &mut Buffer, m: &MVal, type_: &str) -> Option<Out> {
fn pq_action(_buf: &mut Buffer, m: &MVal, type_: &str) -> Option<Out> {
match type_ {
"state of aggregation" => Some(Out::One(Parsed::N(NodeData {
type_: "state of aggregation subscript".into(),
@ -1307,7 +1303,7 @@ fn pu_action(buf: &mut Buffer, m: &MVal, opt: &Option<String>, type_: &str) -> O
MVal::S(s) => vec![s.clone()],
};
let mut ret: Vec<Parsed> = Vec::new();
let g0 = v.get(0).map(|s| s.as_str()).unwrap_or("");
let g0 = v.first().map(|s| s.as_str()).unwrap_or("");
if g0 == "+-" || g0 == "+/-" {
ret.push(Parsed::S("\\pm ".into()));
} else if !g0.is_empty() {
@ -1352,7 +1348,7 @@ fn pu_action(buf: &mut Buffer, m: &MVal, opt: &Option<String>, type_: &str) -> O
MVal::S(s) => vec![s.clone()],
};
let mut ret: Vec<Parsed> = Vec::new();
let g0 = v.get(0).map(|s| s.as_str()).unwrap_or("");
let g0 = v.first().map(|s| s.as_str()).unwrap_or("");
if g0 == "+-" || g0 == "+/-" {
ret.push(Parsed::S("\\pm ".into()));
} else if !g0.is_empty() {

View File

@ -11,15 +11,12 @@
use serde::{Deserialize, Serialize};
/// SQL 补全用 schema 数据,由 `get_db_schema` server function 填充。
// 暂未被消费Task 5 的 get_db_schema 会用到),先 allow dead_code 避免 -D warnings 阻断 clippy。
#[allow(dead_code)]
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
pub struct SqlSchema {
pub tables: Vec<SqlTable>,
}
/// 单张表的补全数据:表名 + 列名列表。
#[allow(dead_code)]
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct SqlTable {
pub name: String,

View File

@ -50,7 +50,7 @@ fn route_cache_dir(route: &str) -> Option<PathBuf> {
path.push(seg);
}
if path.as_path() == std::path::Path::new(SSR_CACHE_ROOT) {
None // 根路由("/"单独由 invalidate_ssr_home 处理
None // 根路由("/"无目录段;首页缓存由 invalidate_ssr_all_public 覆盖删除
} else {
Some(path)
}
@ -72,19 +72,6 @@ pub fn invalidate_ssr_route(route: &str) {
}
}
/// 失效首页 SSR 缓存(路由 `/`,落盘在 `static/index/`)。
///
/// 通常 [`invalidate_ssr_all_public`] 已覆盖首页;本函数留作只需刷新首页的细粒度场景。
#[allow(dead_code)]
pub fn invalidate_ssr_home() {
let dir = PathBuf::from(SSR_CACHE_ROOT).join("index");
match std::fs::remove_dir_all(&dir) {
Ok(()) => tracing::debug!("SSR 首页缓存已删除"),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => tracing::warn!(error = %e, "删除 SSR 首页缓存失败"),
}
}
/// 失效所有公开页 SSR 缓存(删除 `static/` 下除 `.well-known`、`admin` 外的全部)。
///
/// 用于批量重建等影响面广的写入。保留 `.well-known`(浏览器/PWA 元数据,
@ -112,7 +99,7 @@ pub fn invalidate_ssr_all_public() {
/// 原子递增并返回新的全局世代号。
///
/// 仅作可观测性用途(注入 `X-SSR-Generation` 响应头)。实际 SSR 缓存失效由
/// [`invalidate_ssr_route`] / [`invalidate_ssr_home`] 物理删文件完成
/// [`invalidate_ssr_route`] 物理删文件完成(首页由 [`invalidate_ssr_all_public`] 覆盖)
pub fn bump_global_generation() -> u64 {
let new = GLOBAL_GENERATION
.fetch_add(1, Ordering::SeqCst)
@ -164,7 +151,7 @@ mod tests {
#[test]
fn route_cache_dir_none_for_root() {
// 根路由 "/" 无目录段,由 invalidate_ssr_home 单独处理
// 根路由 "/" 无目录段(首页缓存由 invalidate_ssr_all_public 覆盖)
assert!(route_cache_dir("/").is_none());
assert!(route_cache_dir("").is_none());
}
@ -195,6 +182,5 @@ mod tests {
// (若真实环境已有 static/本测试不会误删——read_dir 对每个条目单独删,
// 这里仅验证根缺失分支。)
invalidate_ssr_all_public();
invalidate_ssr_home();
}
}