wx-sdk 0.0.9

A Wechat SDK written in Rust
Documentation
use crate::{
    error::SdkError,
    mp::event::{xmlutil::get_text_from_root, ReceivedMessageParser},
    SdkResult,
};

pub struct ScanEvent {
    pub event_key: String,
    pub ticket: String,
}

impl ReceivedMessageParser for ScanEvent {
    type ReceivedMessage = ScanEvent;

    fn from_xml(node: &roxmltree::Node) -> SdkResult<Self::ReceivedMessage> {
        let event_key = get_text_from_root(node, "EventKey")?;
        let ticket = get_text_from_root(node, "Ticket")?;
        Ok(ScanEvent {
            event_key: event_key.to_string(),
            ticket: ticket.to_string(),
        })
    }
}

pub struct MenuScanEvent {
    pub event_key: String,
    pub scan_type: String,
    pub scan_result: String,
}

impl ReceivedMessageParser for MenuScanEvent {
    type ReceivedMessage = MenuScanEvent;

    fn from_xml(node: &roxmltree::Node) -> SdkResult<Self::ReceivedMessage> {
        let event_key = get_text_from_root(node, "EventKey")?;
        let scan_code_info = node
            .descendants()
            .find(|n| n.has_tag_name("ScanCodeInfo"))
            .ok_or_else(|| {
                SdkError::InvalidParams(format!(
                    "Parse XML msg from wechat error: tag `{}` is none",
                    "ScanCodeInfo"
                ))
            })?;
        let scan_type = get_text_from_root(&scan_code_info, "ScanType")?;
        let scan_result = get_text_from_root(&scan_code_info, "ScanResult")?;
        let event = MenuScanEvent {
            event_key: event_key.to_owned(),
            scan_type: scan_type.to_owned(),
            scan_result: scan_result.to_owned(),
        };
        Ok(event)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::SdkResult;

    #[test]
    pub fn parse() -> SdkResult<()> {
        use roxmltree::Document;
        let s = "<xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[FromUser]]></FromUserName>
    <CreateTime>123456789</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[SCAN]]></Event>
    <EventKey><![CDATA[SCENE_VALUE]]></EventKey>
    <Ticket><![CDATA[TICKET]]></Ticket>
  </xml>";
        let node = Document::parse(&s)?;
        let msg = ScanEvent::from_xml(&node.root())?;

        assert_eq!(msg.event_key, "SCENE_VALUE");
        Ok(())
    }

    #[test]
    pub fn parse_menuscan() -> SdkResult<()> {
        use roxmltree::Document;
        let s = "<xml>
    <FromUserName><![CDATA[oMgHVjngRipVsoxg6TuX3vz6glDg]]></FromUserName>
    <CreateTime>1408090502</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[scancode_push]]></Event>
    <EventKey><![CDATA[6]]></EventKey>
    <ScanCodeInfo><ScanType><![CDATA[qrcode]]></ScanType>
    <ScanResult><![CDATA[1]]></ScanResult>
    </ScanCodeInfo>
  </xml>";
        let node = Document::parse(&s)?;
        let msg = MenuScanEvent::from_xml(&node.root())?;

        assert_eq!(msg.event_key, "6");
        assert_eq!(msg.scan_type, "qrcode");
        assert_eq!(msg.scan_result, "1");
        Ok(())
    }
}