wx-sdk 0.0.9

A Wechat SDK written in Rust
Documentation
use crate::{
    mp::{
        event::{
            xmlutil::{get_node_by_tag, get_number_from_root, get_text_from_root},
            ReceivedMessageParser,
        },
        freepublish::{ArticleDetail, ArticleDetailItem},
    },
    SdkResult,
};
use roxmltree::Node;
use serde::{Deserialize, Serialize};

pub enum PublishJobFinishEvent {
    Success {
        publish_id: String,
        publish_status: i8,
        article_id: String,
        article_detail: ArticleDetail,
    },
    Fail {
        publish_id: String,
        publish_status: i8,
        fail_id: Vec<i8>,
    },
}

impl ReceivedMessageParser for PublishJobFinishEvent {
    type ReceivedMessage = PublishJobFinishEvent;

    fn from_xml(node: &roxmltree::Node) -> crate::SdkResult<Self::ReceivedMessage> {
        let publish_event_info = get_node_by_tag(node, "PublishEventInfo")?;
        let publish_id = get_text_from_root(&publish_event_info, "publish_id")?.to_string();
        let publish_status = get_number_from_root::<i8>(&publish_event_info, "publish_status")?;
        if publish_status == 0 {
            let article_id = get_text_from_root(&publish_event_info, "article_id")?.to_string();
            let article_detail = get_node_by_tag(&publish_event_info, "article_detail")?;
            let count = get_number_from_root::<i8>(&article_detail, "count")?;
            let article_list: Vec<Node> = article_detail
                .descendants()
                .filter(|n| n.has_tag_name("item"))
                .collect();
            let article_list: Vec<ArticleDetailItem> = article_list
                .iter()
                .map(|n| {
                    let idx = n
                        .first_child()
                        .unwrap()
                        .text()
                        .unwrap()
                        .parse::<i8>()
                        .unwrap();
                    let article_url = n
                        .descendants()
                        .find(|n| n.has_tag_name("article_url"))
                        .unwrap()
                        .text()
                        .unwrap()
                        .to_string();
                    ArticleDetailItem { idx, article_url }
                })
                .collect();
            let article_detail = ArticleDetail {
                count,
                item: article_list,
            };
            Ok(PublishJobFinishEvent::Success {
                publish_id,
                publish_status,
                article_id,
                article_detail,
            })
        } else {
            let fail_id: Vec<i8> = publish_event_info
                .descendants()
                .filter(|n| n.has_tag_name("fail_idx"))
                .map(|n| n.text().unwrap().parse::<i8>().unwrap())
                .collect();
            Ok(PublishJobFinishEvent::Fail {
                publish_id,
                publish_status,
                fail_id,
            })
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::SdkResult;
    #[test]
    pub fn parse() -> SdkResult<()> {
        use crate::mp::event::EventMessage;
        use roxmltree::Document;
        let s = "<xml> 
        <ToUserName><![CDATA[gh_4d00ed8d6399]]></ToUserName>  
        <FromUserName><![CDATA[oV5CrjpxgaGXNHIQigzNlgLTnwic]]></FromUserName>  
        <CreateTime>1481013459</CreateTime>
        <MsgType><![CDATA[event]]></MsgType>
        <Event><![CDATA[PUBLISHJOBFINISH]]></Event>
        <PublishEventInfo>
          <publish_id>2247503051</publish_id>
          <publish_status>2</publish_status>
          <fail_idx>1</fail_idx>
          <fail_idx>2</fail_idx>
        </PublishEventInfo>
      </xml>
      ";
        let node = Document::parse(&s)?;
        let msg = PublishJobFinishEvent::from_xml(&node.root())?;

        matches!(msg, PublishJobFinishEvent::Fail { .. });
        let s = "<xml> 
  <ToUserName><![CDATA[gh_4d00ed8d6399]]></ToUserName>  
  <FromUserName><![CDATA[oV5CrjpxgaGXNHIQigzNlgLTnwic]]></FromUserName>  
  <CreateTime>1481013459</CreateTime>
  <MsgType><![CDATA[event]]></MsgType>
  <Event><![CDATA[PUBLISHJOBFINISH]]></Event>
  <PublishEventInfo>
    <publish_id>2247503051</publish_id>
    <publish_status>0</publish_status>
    <article_id><![CDATA[b5O2OUs25HBxRceL7hfReg-U9QGeq9zQjiDvy
WP4Hq4]]></article_id>
    <article_detail>
      <count>1</count>
      <item>
        <idx>1</idx>
        <article_url><![CDATA[ARTICLE_URL]]></article_url>
      </item>
    </article_detail>
  </PublishEventInfo>
</xml>
";
        let msg = Document::parse(s)?;
        let msg = PublishJobFinishEvent::from_xml(&node.root())?;
        matches!(msg, PublishJobFinishEvent::Success { .. });
        Ok(())
    }
}