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:
parent
6276bab6c6
commit
17d596c512
@ -417,26 +417,6 @@ pub async fn get_user_by_token(token: &str) -> Result<Option<SessionUser>, Serve
|
|||||||
Ok(user)
|
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` 路径下。
|
/// Dioxus server function,注册在 `/api` 路径下。
|
||||||
|
|||||||
@ -51,16 +51,8 @@ enum Field {
|
|||||||
Nodes(Vec<Parsed>),
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
enum Parsed {
|
enum Parsed {
|
||||||
S(String),
|
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")),
|
||||||
"x$" => re_match(re!("^x$")),
|
"x$" => re_match(re!("^x$")),
|
||||||
"i$" => re_match(re!("^i$")),
|
"i$" => re_match(re!("^i$")),
|
||||||
"letters" => re_match(&*LETTERS_RE),
|
"letters" => re_match(&LETTERS_RE),
|
||||||
"\\greek" => re_match(&*GREEK_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 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]+")),
|
"digits" => re_match(re!("^[0-9]+")),
|
||||||
"-9.,9" => re_match(re!("^[+\\-]?(?:[0-9]+(?:[,.][0-9]+)?|[0-9]*(?:\\.[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]+)?")),
|
"-9.,9 no missing 0" => re_match(re!("^[+\\-]?[0-9]+(?:[.,][0-9]+)?")),
|
||||||
@ -596,6 +588,7 @@ fn mval_str(m: &MVal) -> String {
|
|||||||
// 状态机主循环(对应 `_mhchemParser.go`)
|
// 状态机主循环(对应 `_mhchemParser.go`)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
|
#[allow(clippy::large_enum_variant)] // 同上:Out 为动作返回值,瞬态使用
|
||||||
enum Out {
|
enum Out {
|
||||||
None,
|
None,
|
||||||
One(Parsed),
|
One(Parsed),
|
||||||
@ -622,8 +615,10 @@ fn go(input: &str, machine: &str) -> Vec<Parsed> {
|
|||||||
|
|
||||||
let transitions = transitions_for(machine);
|
let transitions = transitions_for(machine);
|
||||||
let mut state = String::from("0");
|
let mut state = String::from("0");
|
||||||
let mut buffer = Buffer::default();
|
let mut buffer = Buffer {
|
||||||
buffer.parenthesis_level = 0;
|
parenthesis_level: 0,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
let mut output: Vec<Parsed> = Vec::new();
|
let mut output: Vec<Parsed> = Vec::new();
|
||||||
let mut last_input: Option<String> = None;
|
let mut last_input: Option<String> = None;
|
||||||
let mut watchdog = 10i32;
|
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) {
|
if let (Some(a), MVal::V(v)) = (opt, m) {
|
||||||
Out::One(Parsed::N(NodeData {
|
Out::One(Parsed::N(NodeData {
|
||||||
type_: a.clone(),
|
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())),
|
p2: Some(Field::Str(v.get(1).cloned().unwrap_or_default())),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
}))
|
||||||
|
|||||||
@ -2,10 +2,6 @@
|
|||||||
// 数据机械移植自 mhchemParser 4.2.2 的 `stateMachines`。
|
// 数据机械移植自 mhchemParser 4.2.2 的 `stateMachines`。
|
||||||
// (被 include 进 mhchem.rs 中部,故不能用 `//!` 内部文档注释。)
|
// (被 include 进 mhchem.rs 中部,故不能用 `//!` 内部文档注释。)
|
||||||
|
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
// ── Task 构造器 ──────────────────────────────────────────────────────────
|
// ── Task 构造器 ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
fn task(acts: &[(&str, Option<&str>)], next: Option<&str>, revisit: bool, cont: bool) -> 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_ {
|
match type_ {
|
||||||
"state of aggregation" => Some(Out::One(Parsed::N(NodeData {
|
"state of aggregation" => Some(Out::One(Parsed::N(NodeData {
|
||||||
type_: "state of aggregation subscript".into(),
|
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()],
|
MVal::S(s) => vec![s.clone()],
|
||||||
};
|
};
|
||||||
let mut ret: Vec<Parsed> = Vec::new();
|
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 == "+/-" {
|
if g0 == "+-" || g0 == "+/-" {
|
||||||
ret.push(Parsed::S("\\pm ".into()));
|
ret.push(Parsed::S("\\pm ".into()));
|
||||||
} else if !g0.is_empty() {
|
} 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()],
|
MVal::S(s) => vec![s.clone()],
|
||||||
};
|
};
|
||||||
let mut ret: Vec<Parsed> = Vec::new();
|
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 == "+/-" {
|
if g0 == "+-" || g0 == "+/-" {
|
||||||
ret.push(Parsed::S("\\pm ".into()));
|
ret.push(Parsed::S("\\pm ".into()));
|
||||||
} else if !g0.is_empty() {
|
} else if !g0.is_empty() {
|
||||||
|
|||||||
@ -11,15 +11,12 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// SQL 补全用 schema 数据,由 `get_db_schema` server function 填充。
|
/// 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)]
|
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
|
||||||
pub struct SqlSchema {
|
pub struct SqlSchema {
|
||||||
pub tables: Vec<SqlTable>,
|
pub tables: Vec<SqlTable>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 单张表的补全数据:表名 + 列名列表。
|
/// 单张表的补全数据:表名 + 列名列表。
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct SqlTable {
|
pub struct SqlTable {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|||||||
@ -50,7 +50,7 @@ fn route_cache_dir(route: &str) -> Option<PathBuf> {
|
|||||||
path.push(seg);
|
path.push(seg);
|
||||||
}
|
}
|
||||||
if path.as_path() == std::path::Path::new(SSR_CACHE_ROOT) {
|
if path.as_path() == std::path::Path::new(SSR_CACHE_ROOT) {
|
||||||
None // 根路由("/")单独由 invalidate_ssr_home 处理
|
None // 根路由("/")无目录段;首页缓存由 invalidate_ssr_all_public 覆盖删除
|
||||||
} else {
|
} else {
|
||||||
Some(path)
|
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` 外的全部)。
|
/// 失效所有公开页 SSR 缓存(删除 `static/` 下除 `.well-known`、`admin` 外的全部)。
|
||||||
///
|
///
|
||||||
/// 用于批量重建等影响面广的写入。保留 `.well-known`(浏览器/PWA 元数据,
|
/// 用于批量重建等影响面广的写入。保留 `.well-known`(浏览器/PWA 元数据,
|
||||||
@ -112,7 +99,7 @@ pub fn invalidate_ssr_all_public() {
|
|||||||
/// 原子递增并返回新的全局世代号。
|
/// 原子递增并返回新的全局世代号。
|
||||||
///
|
///
|
||||||
/// 仅作可观测性用途(注入 `X-SSR-Generation` 响应头)。实际 SSR 缓存失效由
|
/// 仅作可观测性用途(注入 `X-SSR-Generation` 响应头)。实际 SSR 缓存失效由
|
||||||
/// [`invalidate_ssr_route`] / [`invalidate_ssr_home`] 物理删文件完成。
|
/// [`invalidate_ssr_route`] 物理删文件完成(首页由 [`invalidate_ssr_all_public`] 覆盖)。
|
||||||
pub fn bump_global_generation() -> u64 {
|
pub fn bump_global_generation() -> u64 {
|
||||||
let new = GLOBAL_GENERATION
|
let new = GLOBAL_GENERATION
|
||||||
.fetch_add(1, Ordering::SeqCst)
|
.fetch_add(1, Ordering::SeqCst)
|
||||||
@ -164,7 +151,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn route_cache_dir_none_for_root() {
|
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());
|
||||||
assert!(route_cache_dir("").is_none());
|
assert!(route_cache_dir("").is_none());
|
||||||
}
|
}
|
||||||
@ -195,6 +182,5 @@ mod tests {
|
|||||||
// (若真实环境已有 static/,本测试不会误删——read_dir 对每个条目单独删,
|
// (若真实环境已有 static/,本测试不会误删——read_dir 对每个条目单独删,
|
||||||
// 这里仅验证根缺失分支。)
|
// 这里仅验证根缺失分支。)
|
||||||
invalidate_ssr_all_public();
|
invalidate_ssr_all_public();
|
||||||
invalidate_ssr_home();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user