Skip to main content

wx_sdk/mp/event/msg_event/
event_scan.rs

1use crate::{
2    error::SdkError,
3    mp::event::{xmlutil::get_text_from_root, ReceivedMessageParser},
4    SdkResult,
5};
6
7pub struct ScanEvent {
8    pub event_key: String,
9    pub ticket: String,
10}
11
12impl ReceivedMessageParser for ScanEvent {
13    type ReceivedMessage = ScanEvent;
14
15    fn from_xml(node: &roxmltree::Node) -> SdkResult<Self::ReceivedMessage> {
16        let event_key = get_text_from_root(node, "EventKey")?;
17        let ticket = get_text_from_root(node, "Ticket")?;
18        Ok(ScanEvent {
19            event_key: event_key.to_string(),
20            ticket: ticket.to_string(),
21        })
22    }
23}
24
25pub struct MenuScanEvent {
26    pub event_key: String,
27    pub scan_type: String,
28    pub scan_result: String,
29}
30
31impl ReceivedMessageParser for MenuScanEvent {
32    type ReceivedMessage = MenuScanEvent;
33
34    fn from_xml(node: &roxmltree::Node) -> SdkResult<Self::ReceivedMessage> {
35        let event_key = get_text_from_root(node, "EventKey")?;
36        let scan_code_info = node
37            .descendants()
38            .find(|n| n.has_tag_name("ScanCodeInfo"))
39            .ok_or_else(|| {
40                SdkError::InvalidParams(format!(
41                    "Parse XML msg from wechat error: tag `{}` is none",
42                    "ScanCodeInfo"
43                ))
44            })?;
45        let scan_type = get_text_from_root(&scan_code_info, "ScanType")?;
46        let scan_result = get_text_from_root(&scan_code_info, "ScanResult")?;
47        let event = MenuScanEvent {
48            event_key: event_key.to_owned(),
49            scan_type: scan_type.to_owned(),
50            scan_result: scan_result.to_owned(),
51        };
52        Ok(event)
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59    use crate::SdkResult;
60
61    #[test]
62    pub fn parse() -> SdkResult<()> {
63        use roxmltree::Document;
64        let s = "<xml>
65    <ToUserName><![CDATA[toUser]]></ToUserName>
66    <FromUserName><![CDATA[FromUser]]></FromUserName>
67    <CreateTime>123456789</CreateTime>
68    <MsgType><![CDATA[event]]></MsgType>
69    <Event><![CDATA[SCAN]]></Event>
70    <EventKey><![CDATA[SCENE_VALUE]]></EventKey>
71    <Ticket><![CDATA[TICKET]]></Ticket>
72  </xml>";
73        let node = Document::parse(&s)?;
74        let msg = ScanEvent::from_xml(&node.root())?;
75
76        assert_eq!(msg.event_key, "SCENE_VALUE");
77        Ok(())
78    }
79
80    #[test]
81    pub fn parse_menuscan() -> SdkResult<()> {
82        use roxmltree::Document;
83        let s = "<xml>
84    <FromUserName><![CDATA[oMgHVjngRipVsoxg6TuX3vz6glDg]]></FromUserName>
85    <CreateTime>1408090502</CreateTime>
86    <MsgType><![CDATA[event]]></MsgType>
87    <Event><![CDATA[scancode_push]]></Event>
88    <EventKey><![CDATA[6]]></EventKey>
89    <ScanCodeInfo><ScanType><![CDATA[qrcode]]></ScanType>
90    <ScanResult><![CDATA[1]]></ScanResult>
91    </ScanCodeInfo>
92  </xml>";
93        let node = Document::parse(&s)?;
94        let msg = MenuScanEvent::from_xml(&node.root())?;
95
96        assert_eq!(msg.event_key, "6");
97        assert_eq!(msg.scan_type, "qrcode");
98        assert_eq!(msg.scan_result, "1");
99        Ok(())
100    }
101}