Skip to main content

tdm_server_rust/utils/
rss_labels.rs

1//! RSS 文案生成工具 (RSS Label Utilities)
2//!
3//! 分类描述、岗位标签、人员格式化等 RSS 展示文案的查询函数。
4//! 对齐 Java `GeneralUtils` 及各枚举类的 `toChinese()` 方法。
5//!
6//! ## 设计
7//!
8//! 每个函数对应一个枚举或映射表的"转中文"逻辑,
9//! 输入为数字编码或英文岗位名,输出为中文展示文本。
10
11use chrono::{DateTime, Datelike, Timelike, Utc};
12use crate::entity::manga::CollectedMembersVo;
13use crate::utils::shanghai_time::shanghai_offset;
14
15/// 漫画分类编码 → 中文描述
16///
17/// # 映射表
18///
19/// | 编码 | 描述 |
20/// |------|------|
21/// | 1 | 长篇连载 |
22/// | 2 | 短篇漫画 |
23/// | 3 | 漫画合集 |
24/// | 4 | 百合动画 |
25pub fn category_label(code: i16) -> &'static str {
26    match code {
27        1 => "长篇连载",
28        2 => "短篇漫画",
29        3 => "漫画合集",
30        4 => "百合动画",
31        _ => "",
32    }
33}
34
35/// 漫画连载状态编码 → 中文描述
36///
37/// # 映射表
38///
39/// | 编码 | 描述 |
40/// |------|------|
41/// | 1 | 正常连载中 |
42/// | 2 | ☆求人中☆ |
43/// | 3 | 现在立刻非常需要人手! |
44/// | 4 | 已完结 |
45/// | 5 | 暂时搁置 |
46/// | 6 | 已腰斩 |
47/// | 7 | 已弃坑 |
48/// | 8 | 作者不更新 |
49pub fn manga_status_label(code: i16) -> &'static str {
50    match code {
51        1 => "正常连载中",
52        2 => "☆求人中☆",
53        3 => "现在立刻非常需要人手!",
54        4 => "已完结",
55        5 => "暂时搁置",
56        6 => "已腰斩",
57        7 => "已弃坑",
58        8 => "作者不更新",
59        _ => "",
60    }
61}
62
63/// 组员职阶编码 → 中文描述
64///
65/// # 映射表
66///
67/// | 编码 | 描述 |
68/// |------|------|
69/// | 0 | 正式组员 |
70/// | 1 | 实习组员 |
71/// | 2 | 暂不接稿 |
72/// | 3 | 退休组员 |
73/// | 4 | 已退组 |
74pub fn intern_label(intern: i16) -> &'static str {
75    match intern {
76        0 => "正式组员",
77        1 => "实习组员",
78        2 => "暂不接稿",
79        3 => "退休组员",
80        4 => "已退组",
81        _ => "",
82    }
83}
84
85/// 当前交稿岗位英文名 → 中文名
86///
87/// 用于工作提醒 RSS 中显示"翻译已完成,校对请接稿"等文案。
88pub fn current_post_label(my_name: &str) -> &'static str {
89    match my_name.to_lowercase().as_str() {
90        "provider" => "图源",
91        "translator" => "翻译",
92        "proofreader" => "校对",
93        "letterer" => "嵌字",
94        "reviewer" => "审稿",
95        "timer" => "时轴",
96        "publisher" => "发布",
97        _ => "",
98    }
99}
100
101/// 下一工序岗位英文名 → 中文名
102///
103/// 对齐 Java `PostEnum.getNextLabel`,指示当前岗位交稿后由谁接稿。
104///
105/// # 流水线
106///
107/// | 当前岗位 | 下一工序 |
108/// |----------|----------|
109/// | provider(图源) | 翻译 |
110/// | translator(翻译) | 校对 |
111/// | proofreader(校对) | 嵌字 |
112/// | letterer(嵌字) | 审稿 |
113/// | timer(时轴) | 审稿 |
114pub fn next_post_label(my_name: &str) -> &'static str {
115    match my_name.to_lowercase().as_str() {
116        "provider" => "翻译",
117        "translator" => "校对",
118        "proofreader" => "嵌字",
119        "letterer" => "审稿",
120        "timer" => "审稿",
121        _ => "",
122    }
123}
124
125/// UTC 时间 → 中文格式字符串
126///
127/// 转为上海时区后格式化为"X年X月X日X点X分"。
128/// 对应 Java `GeneralUtils.formatTime`。
129///
130/// # 参数
131///
132/// - `time`: UTC 时间,`None` 时返回空字符串
133pub fn format_rss_time(time: Option<DateTime<Utc>>) -> String {
134    let Some(t) = time else {
135        return String::new();
136    };
137    let local = t.with_timezone(&shanghai_offset());
138    format!(
139        "{}年{}月{}日{}点{}分",
140        local.year(),
141        local.month(),
142        local.day(),
143        local.hour(),
144        local.minute()
145    )
146}
147
148/// 收藏组员列表 → RSS 作者字符串
149///
150/// 格式化为 `"name1. name2. name3. "` 的连续字符串。
151pub fn format_members(members: &[CollectedMembersVo]) -> String {
152    members
153        .iter()
154        .filter_map(|m| m.username.as_deref())
155        .map(|name| format!("{name}. "))
156        .collect()
157}
158
159/// 分类 + 连载状态 → RSS category 字段
160///
161/// 组合为 `"长短篇:{cat} 连载状态:{st}"` 格式。
162pub fn rss_category(category: Option<i16>, manga_status: Option<i16>) -> String {
163    let cat = category.map(category_label).unwrap_or("");
164    let st = manga_status.map(manga_status_label).unwrap_or("");
165    format!("长短篇:{cat} 连载状态:{st}")
166}