wechat_minapp/minapp_security/
mod.rs

1//! 微信小程序内容安全检测模块
2//!
3//! - [`msg_sec_check`][]: 文本内容安全检测。
4//!
5
6mod msg_sec_check;
7
8use serde::{Deserialize, Serialize};
9use serde_repr::Deserialize_repr;
10use strum::Display;
11
12pub use msg_sec_check::{Args, MsgSecCheckResult, Scene};
13
14#[derive(Debug, Deserialize_repr, Display, Serialize, PartialEq, Clone)]
15#[repr(i32)]
16pub enum Label {
17    #[strum(serialize = "正常")]
18    Normal = 100,
19
20    #[strum(serialize = "广告")]
21    Ad = 10001,
22
23    #[strum(serialize = "时政")]
24    Politics = 20001,
25
26    #[strum(serialize = "色情")]
27    Porn = 20002,
28
29    #[strum(serialize = "辱骂")]
30    Abuse = 20003,
31
32    #[strum(serialize = "违法犯罪")]
33    Illegal = 20006,
34
35    #[strum(serialize = "欺诈")]
36    Fraud = 20008,
37
38    #[strum(serialize = "低俗")]
39    Vulgar = 20012,
40
41    #[strum(serialize = "版权")]
42    Copyright = 20013,
43
44    #[strum(serialize = "其他")]
45    Other = 21000,
46}
47
48// 可选:为方便使用,可以添加一些辅助方法
49impl Label {
50    /// 根据数值获取对应的标签枚举
51    pub fn from_value(value: i32) -> Option<Self> {
52        match value {
53            100 => Some(Label::Normal),
54            10001 => Some(Label::Ad),
55            20001 => Some(Label::Politics),
56            20002 => Some(Label::Porn),
57            20003 => Some(Label::Abuse),
58            20006 => Some(Label::Illegal),
59            20008 => Some(Label::Fraud),
60            20012 => Some(Label::Vulgar),
61            20013 => Some(Label::Copyright),
62            21000 => Some(Label::Other),
63            _ => None,
64        }
65    }
66
67    /// 检查是否为正常内容
68    pub fn is_normal(&self) -> bool {
69        matches!(self, Label::Normal)
70    }
71
72    /// 检查是否为违规内容
73    pub fn is_violation(&self) -> bool {
74        !self.is_normal()
75    }
76}
77
78/// 内容安全检测建议
79#[derive(Debug, Deserialize, Serialize, Display, PartialEq, Clone)]
80pub enum Suggest {
81    #[strum(serialize = "risky")]
82    #[serde(rename = "risky")]
83    Risky,
84
85    #[strum(serialize = "pass")]
86    #[serde(rename = "pass")]
87    Pass,
88
89    #[strum(serialize = "review")]
90    #[serde(rename = "review")]
91    Review,
92}
93
94// 可选:为方便使用,可以添加一些辅助方法
95impl Suggest {
96    /// 检查是否通过
97    pub fn is_pass(&self) -> bool {
98        matches!(self, Suggest::Pass)
99    }
100
101    /// 检查是否有风险
102    pub fn is_risky(&self) -> bool {
103        matches!(self, Suggest::Risky)
104    }
105
106    /// 检查是否需要人工审核
107    pub fn needs_review(&self) -> bool {
108        matches!(self, Suggest::Review)
109    }
110
111    /// 获取建议的优先级(数值越小优先级越高)
112    pub fn priority(&self) -> u8 {
113        match self {
114            Suggest::Risky => 1,  // 最高优先级:有风险
115            Suggest::Review => 2, // 中等优先级:需要审核
116            Suggest::Pass => 3,   // 最低优先级:通过
117        }
118    }
119}
120
121impl From<&str> for Suggest {
122    fn from(s: &str) -> Self {
123        match s.to_lowercase().as_str() {
124            "risky" => Suggest::Risky,
125            "pass" => Suggest::Pass,
126            "review" => Suggest::Review,
127            _ => Suggest::Review,
128        }
129    }
130}
131
132#[cfg(test)]
133mod tests {
134    use super::*;
135
136    #[test]
137    fn test_suggest_enum() {
138        // 测试显示功能
139        assert_eq!(Suggest::Risky.to_string(), "risky");
140        assert_eq!(Suggest::Pass.to_string(), "pass");
141        assert_eq!(Suggest::Review.to_string(), "review");
142
143        // 测试从字符串创建
144        assert_eq!(Suggest::from("risky"), Suggest::Risky);
145        assert_eq!(Suggest::from("PASS"), Suggest::Pass);
146        assert_eq!(Suggest::from("ReViEw"), Suggest::Review);
147        assert_eq!(Suggest::from("invalid"), Suggest::Review);
148
149        // 测试辅助方法
150        assert!(Suggest::Pass.is_pass());
151        assert!(Suggest::Risky.is_risky());
152        assert!(Suggest::Review.needs_review());
153
154        // 测试优先级
155        assert_eq!(Suggest::Risky.priority(), 1);
156        assert_eq!(Suggest::Review.priority(), 2);
157        assert_eq!(Suggest::Pass.priority(), 3);
158    }
159
160    #[test]
161    fn test_serialization() {
162        // 测试序列化
163        let risky_json = serde_json::to_string(&Suggest::Risky).unwrap();
164        assert_eq!(risky_json, "\"risky\"");
165
166        let pass_json = serde_json::to_string(&Suggest::Pass).unwrap();
167        assert_eq!(pass_json, "\"pass\"");
168
169        // 测试反序列化
170        let review: Suggest = serde_json::from_str("\"review\"").unwrap();
171        assert_eq!(review, Suggest::Review);
172    }
173}