xmpp_codec.rs

  1use std;
  2use std::str::from_utf8;
  3use std::io::{Error, ErrorKind};
  4use std::collections::HashMap;
  5use tokio_core::io::{Codec, EasyBuf};
  6use xml;
  7
  8const NS_XMLNS: &'static str = "http://www.w3.org/2000/xmlns/";
  9const NS_STREAMS: &'static str = "http://etherx.jabber.org/streams";
 10const NS_CLIENT: &'static str = "jabber:client";
 11
 12struct XMPPRoot {
 13    builder: xml::ElementBuilder,
 14    pub attributes: HashMap<(String, Option<String>), String>,
 15}
 16
 17impl XMPPRoot {
 18    fn new(root: xml::StartTag) -> Self {
 19        let mut builder = xml::ElementBuilder::new();
 20        let mut attributes = HashMap::new();
 21        println!("root attributes: {:?}", root.attributes);
 22        for (name_ns, value) in root.attributes {
 23            match name_ns {
 24                (ref name, None) if name == "xmlns" =>
 25                    builder.set_default_ns(value),
 26                (ref prefix, Some(ref ns)) if ns == NS_XMLNS =>
 27                    builder.define_prefix(prefix.to_owned(), value),
 28                _ => {
 29                    attributes.insert(name_ns, value);
 30                },
 31            }
 32        }
 33
 34        XMPPRoot {
 35            builder: builder,
 36            attributes: attributes,
 37        }
 38    }
 39
 40    fn handle_event(&mut self, event: Result<xml::Event, xml::ParserError>)
 41                    -> Option<Result<xml::Element, xml::BuilderError>> {
 42        self.builder.handle_event(event)
 43    }
 44}
 45
 46#[derive(Debug)]
 47pub enum Packet {
 48    Error(Box<std::error::Error>),
 49    StreamStart,
 50    Stanza(xml::Element),
 51    StreamEnd,
 52}
 53
 54pub struct XMPPCodec {
 55    parser: xml::Parser,
 56    root: Option<XMPPRoot>,
 57}
 58
 59impl XMPPCodec {
 60    pub fn new() -> Self {
 61        XMPPCodec {
 62            parser: xml::Parser::new(),
 63            root: None,
 64        }
 65    }
 66}
 67
 68impl Codec for XMPPCodec {
 69    type In = Vec<Packet>;
 70    type Out = Packet;
 71
 72    fn decode(&mut self, buf: &mut EasyBuf) -> Result<Option<Self::In>, Error> {
 73        match from_utf8(buf.as_slice()) {
 74            Ok(s) =>
 75                self.parser.feed_str(s),
 76            Err(e) =>
 77                return Err(Error::new(ErrorKind::InvalidInput, e)),
 78        }
 79
 80        let mut new_root = None;
 81        let mut results = Vec::new();
 82        for event in &mut self.parser {
 83            match &mut self.root {
 84                &mut None => {
 85                    // Expecting <stream:stream>
 86                    match event {
 87                        Ok(xml::Event::ElementStart(start_tag)) => {
 88                            new_root = Some(XMPPRoot::new(start_tag));
 89                            results.push(Packet::StreamStart);
 90                        },
 91                        Err(e) =>
 92                            results.push(Packet::Error(Box::new(e))),
 93                        _ =>
 94                            (),
 95                    }
 96                }
 97
 98                &mut Some(ref mut root) => {
 99                    match root.handle_event(event) {
100                        None => (),
101                        Some(Ok(stanza)) => {
102                            println!("stanza: {}", stanza);
103                            results.push(Packet::Stanza(stanza));
104                        },
105                        Some(Err(e)) =>
106                            results.push(Packet::Error(Box::new(e))),
107                    };
108                },
109            }
110
111            match new_root.take() {
112                None => (),
113                Some(root) => self.root = Some(root),
114            }
115        }
116
117        if results.len() == 0 {
118            Ok(None)
119        } else {
120            Ok(Some(results))
121        }
122    }
123
124    fn encode(&mut self, msg: Self::Out, buf: &mut Vec<u8>) -> Result<(), Error> {
125        match msg {
126            Packet::StreamStart => {
127                let mut write = |s: &str| {
128                    buf.extend_from_slice(s.as_bytes());
129                };
130
131                write("<?xml version='1.0'?>\n");
132                write("<stream:stream");
133                write(" version='1.0'");
134                write(" to='spaceboyz.net'");
135                write(&format!(" xmlns='{}'", NS_CLIENT));
136                write(&format!(" xmlns:stream='{}'", NS_STREAMS));
137                write(">\n");
138
139                Ok(())
140            },
141            // TODO: Implement all
142            _ => Ok(())
143        }
144    }
145
146    fn decode_eof(&mut self, _buf: &mut EasyBuf) -> Result<Self::In, Error> {
147        Ok(vec!())
148    }
149}