wechat_minapp/minapp_security/
mod.rs1pub mod 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
14use crate::client::WechatMinappSDK;
15
16#[derive(Debug, Deserialize_repr, Display, Serialize, PartialEq, Clone)]
17#[repr(i32)]
18pub enum Label {
19 #[strum(serialize = "正常")]
20 Normal = 100,
21
22 #[strum(serialize = "广告")]
23 Ad = 10001,
24
25 #[strum(serialize = "时政")]
26 Politics = 20001,
27
28 #[strum(serialize = "色情")]
29 Porn = 20002,
30
31 #[strum(serialize = "辱骂")]
32 Abuse = 20003,
33
34 #[strum(serialize = "违法犯罪")]
35 Illegal = 20006,
36
37 #[strum(serialize = "欺诈")]
38 Fraud = 20008,
39
40 #[strum(serialize = "低俗")]
41 Vulgar = 20012,
42
43 #[strum(serialize = "版权")]
44 Copyright = 20013,
45
46 #[strum(serialize = "其他")]
47 Other = 21000,
48}
49
50impl Label {
52 pub fn from_value(value: i32) -> Option<Self> {
54 match value {
55 100 => Some(Label::Normal),
56 10001 => Some(Label::Ad),
57 20001 => Some(Label::Politics),
58 20002 => Some(Label::Porn),
59 20003 => Some(Label::Abuse),
60 20006 => Some(Label::Illegal),
61 20008 => Some(Label::Fraud),
62 20012 => Some(Label::Vulgar),
63 20013 => Some(Label::Copyright),
64 21000 => Some(Label::Other),
65 _ => None,
66 }
67 }
68
69 pub fn is_normal(&self) -> bool {
71 matches!(self, Label::Normal)
72 }
73
74 pub fn is_violation(&self) -> bool {
76 !self.is_normal()
77 }
78}
79
80#[derive(Debug, Deserialize, Serialize, Display, PartialEq, Clone)]
82pub enum Suggest {
83 #[strum(serialize = "risky")]
84 #[serde(rename = "risky")]
85 Risky,
86
87 #[strum(serialize = "pass")]
88 #[serde(rename = "pass")]
89 Pass,
90
91 #[strum(serialize = "review")]
92 #[serde(rename = "review")]
93 Review,
94}
95
96impl Suggest {
98 pub fn is_pass(&self) -> bool {
100 matches!(self, Suggest::Pass)
101 }
102
103 pub fn is_risky(&self) -> bool {
105 matches!(self, Suggest::Risky)
106 }
107
108 pub fn needs_review(&self) -> bool {
110 matches!(self, Suggest::Review)
111 }
112
113 pub fn priority(&self) -> u8 {
115 match self {
116 Suggest::Risky => 1, Suggest::Review => 2, Suggest::Pass => 3, }
120 }
121}
122
123impl From<&str> for Suggest {
124 fn from(s: &str) -> Self {
125 match s.to_lowercase().as_str() {
126 "risky" => Suggest::Risky,
127 "pass" => Suggest::Pass,
128 "review" => Suggest::Review,
129 _ => Suggest::Review,
130 }
131 }
132}
133
134pub struct MinappSecurity {
135 pub client: WechatMinappSDK,
136}
137
138impl MinappSecurity {
139 pub fn new(client: WechatMinappSDK) -> Self {
140 MinappSecurity { client }
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_suggest_enum() {
150 assert_eq!(Suggest::Risky.to_string(), "risky");
152 assert_eq!(Suggest::Pass.to_string(), "pass");
153 assert_eq!(Suggest::Review.to_string(), "review");
154
155 assert_eq!(Suggest::from("risky"), Suggest::Risky);
157 assert_eq!(Suggest::from("PASS"), Suggest::Pass);
158 assert_eq!(Suggest::from("ReViEw"), Suggest::Review);
159 assert_eq!(Suggest::from("invalid"), Suggest::Review);
160
161 assert!(Suggest::Pass.is_pass());
163 assert!(Suggest::Risky.is_risky());
164 assert!(Suggest::Review.needs_review());
165
166 assert_eq!(Suggest::Risky.priority(), 1);
168 assert_eq!(Suggest::Review.priority(), 2);
169 assert_eq!(Suggest::Pass.priority(), 3);
170 }
171
172 #[test]
173 fn test_serialization() {
174 let risky_json = serde_json::to_string(&Suggest::Risky).unwrap();
176 assert_eq!(risky_json, "\"risky\"");
177
178 let pass_json = serde_json::to_string(&Suggest::Pass).unwrap();
179 assert_eq!(pass_json, "\"pass\"");
180
181 let review: Suggest = serde_json::from_str("\"review\"").unwrap();
183 assert_eq!(review, Suggest::Review);
184 }
185}