wx-sdk 0.0.9

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

pub struct GuideInviteResultEvent {
    pub guide_account: Option<String>,
    pub guide_openid: Option<String>,
    pub invite_result: i32,
}

impl ReceivedMessageParser for GuideInviteResultEvent {
    type ReceivedMessage = GuideInviteResultEvent;

    fn from_xml(node: &roxmltree::Node) -> SdkResult<Self::ReceivedMessage> {
        let guide_invite_event = node
            .descendants()
            .find(|n| n.has_tag_name("GuideInviteEvent"))
            .ok_or_else(|| {
                SdkError::InvalidParams(format!(
                    "Parse XML msg from wechat error: tag `{}` is none",
                    "GuideInviteEvent"
                ))
            })?;
        let guide_account = get_text_from_root(&guide_invite_event, "guide_account")
            .ok()
            .filter(|s| !s.trim().is_empty())
            .map(|s| s.to_string());
        let guide_openid = get_text_from_root(&guide_invite_event, "guide_openid")
            .ok()
            .filter(|s| !s.trim().is_empty())
            .map(|s| s.to_string());
        if guide_account.is_none() && guide_openid.is_none() {
            return Err(SdkError::InvalidParams(format!("parse GuideInviteEvent error: guide_account and guide_openid should exist at least one of them.")));
        }
        let invite_result = get_number_from_root::<i32>(&guide_invite_event, "invite_result")?;
        Ok(GuideInviteResultEvent {
            guide_account,
            guide_openid,
            invite_result,
        })
    }
}

pub struct GuideQrcodeScanEvent {
    pub qrcode_guide_account: Option<String>,
    pub qrcode_guide_openid: Option<String>,
    pub openid: String,
    pub action: u8,
    pub qrcode_info: String,
}

impl ReceivedMessageParser for GuideQrcodeScanEvent {
    type ReceivedMessage = GuideQrcodeScanEvent;

    fn from_xml(node: &roxmltree::Node) -> SdkResult<Self::ReceivedMessage> {
        let guide_scan_event = node
            .descendants()
            .find(|n| n.has_tag_name("GuideScanEvent"))
            .ok_or_else(|| {
                SdkError::InvalidParams(format!(
                    "Parse XML msg from wechat error: tag `{}` is none",
                    "GuideScanEvent"
                ))
            })?;

        let qrcode_guide_account = get_text_from_root(&guide_scan_event, "qrcode_guide_account")
            .ok()
            .filter(|s| !s.trim().is_empty())
            .map(|s| s.to_string());
        let qrcode_guide_openid = get_text_from_root(&guide_scan_event, "qrcode_guide_openid")
            .ok()
            .filter(|s| !s.trim().is_empty())
            .map(|s| s.to_string());
        if qrcode_guide_account.is_none() && qrcode_guide_openid.is_none() {
            return Err(SdkError::InvalidParams(format!("parse GuideScanEvent error: qrcode_guide_account and qrcode_guide_openid should exist at least one of them.")));
        }

        let action = get_number_from_root::<u8>(&guide_scan_event, "action")?;
        let openid = get_text_from_root(&guide_scan_event, "openid")?;
        let qrcode_info = get_text_from_root(&guide_scan_event, "qrcode_info")?;
        Ok(GuideQrcodeScanEvent {
            qrcode_guide_account,
            qrcode_guide_openid,
            action,
            openid: openid.to_string(),
            qrcode_info: qrcode_info.to_string(),
        })
    }
}

#[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>1546924844</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[guide_qrcode_scan_event]]></Event>
    <GuideScanEvent>
      <qrcode_guide_account><![CDATA[xxx]]></qrcode_guide_account>
      <qrcode_guide_openid><![CDATA[xxx]]></qrcode_guide_openid>
      <openid><![CDATA[xxx]]></openid>
      <action>11</action>
      <qrcode_info><![CDATA[xxx]]></qrcode_info>
    </GuideScanEvent>
  </xml>
  ";
        let node = Document::parse(&s)?;
        let msg = GuideQrcodeScanEvent::from_xml(&node.root())?;
        assert_eq!(msg.qrcode_guide_account, Some("xxx".to_string()));
        assert_eq!(msg.action, 11);
        assert_eq!(msg.qrcode_info, "xxx");
        Ok(())
    }
}