wechat_minapp/minapp_security/
mod.rs1mod msg_sec_check;
2
3use serde::{Deserialize, Serialize};
4use serde_repr::Deserialize_repr;
5use strum::Display;
6
7pub use msg_sec_check::{Args, MsgSecCheckResult, Scene};
8
9#[derive(Debug, Deserialize_repr, Display, Serialize, PartialEq, Clone)]
10#[repr(i32)]
11pub enum Label {
12 #[strum(serialize = "正常")]
13 Normal = 100,
14
15 #[strum(serialize = "广告")]
16 Ad = 10001,
17
18 #[strum(serialize = "时政")]
19 Politics = 20001,
20
21 #[strum(serialize = "色情")]
22 Porn = 20002,
23
24 #[strum(serialize = "辱骂")]
25 Abuse = 20003,
26
27 #[strum(serialize = "违法犯罪")]
28 Illegal = 20006,
29
30 #[strum(serialize = "欺诈")]
31 Fraud = 20008,
32
33 #[strum(serialize = "低俗")]
34 Vulgar = 20012,
35
36 #[strum(serialize = "版权")]
37 Copyright = 20013,
38
39 #[strum(serialize = "其他")]
40 Other = 21000,
41}
42
43impl Label {
45 pub fn from_value(value: i32) -> Option<Self> {
47 match value {
48 100 => Some(Label::Normal),
49 10001 => Some(Label::Ad),
50 20001 => Some(Label::Politics),
51 20002 => Some(Label::Porn),
52 20003 => Some(Label::Abuse),
53 20006 => Some(Label::Illegal),
54 20008 => Some(Label::Fraud),
55 20012 => Some(Label::Vulgar),
56 20013 => Some(Label::Copyright),
57 21000 => Some(Label::Other),
58 _ => None,
59 }
60 }
61
62 pub fn is_normal(&self) -> bool {
64 matches!(self, Label::Normal)
65 }
66
67 pub fn is_violation(&self) -> bool {
69 !self.is_normal()
70 }
71}
72
73#[derive(Debug, Deserialize, Serialize, Display, PartialEq, Clone)]
75pub enum Suggest {
76 #[strum(serialize = "risky")]
77 #[serde(rename = "risky")]
78 Risky,
79
80 #[strum(serialize = "pass")]
81 #[serde(rename = "pass")]
82 Pass,
83
84 #[strum(serialize = "review")]
85 #[serde(rename = "review")]
86 Review,
87}
88
89impl Suggest {
91 pub fn is_pass(&self) -> bool {
93 matches!(self, Suggest::Pass)
94 }
95
96 pub fn is_risky(&self) -> bool {
98 matches!(self, Suggest::Risky)
99 }
100
101 pub fn needs_review(&self) -> bool {
103 matches!(self, Suggest::Review)
104 }
105
106 pub fn priority(&self) -> u8 {
108 match self {
109 Suggest::Risky => 1, Suggest::Review => 2, Suggest::Pass => 3, }
113 }
114}
115
116impl From<&str> for Suggest {
117 fn from(s: &str) -> Self {
118 match s.to_lowercase().as_str() {
119 "risky" => Suggest::Risky,
120 "pass" => Suggest::Pass,
121 "review" => Suggest::Review,
122 _ => Suggest::Review,
123 }
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130
131 #[test]
132 fn test_suggest_enum() {
133 assert_eq!(Suggest::Risky.to_string(), "risky");
135 assert_eq!(Suggest::Pass.to_string(), "pass");
136 assert_eq!(Suggest::Review.to_string(), "review");
137
138 assert_eq!(Suggest::from("risky"), Suggest::Risky);
140 assert_eq!(Suggest::from("PASS"), Suggest::Pass);
141 assert_eq!(Suggest::from("ReViEw"), Suggest::Review);
142 assert_eq!(Suggest::from("invalid"), Suggest::Review);
143
144 assert!(Suggest::Pass.is_pass());
146 assert!(Suggest::Risky.is_risky());
147 assert!(Suggest::Review.needs_review());
148
149 assert_eq!(Suggest::Risky.priority(), 1);
151 assert_eq!(Suggest::Review.priority(), 2);
152 assert_eq!(Suggest::Pass.priority(), 3);
153 }
154
155 #[test]
156 fn test_serialization() {
157 let risky_json = serde_json::to_string(&Suggest::Risky).unwrap();
159 assert_eq!(risky_json, "\"risky\"");
160
161 let pass_json = serde_json::to_string(&Suggest::Pass).unwrap();
162 assert_eq!(pass_json, "\"pass\"");
163
164 let review: Suggest = serde_json::from_str("\"review\"").unwrap();
166 assert_eq!(review, Suggest::Review);
167 }
168}