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, Framed};
  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 type XMPPStream<T> = Framed<T, XMPPCodec>;
 55
 56pub struct XMPPCodec {
 57    parser: xml::Parser,
 58    root: Option<XMPPRoot>,
 59}
 60
 61impl XMPPCodec {
 62    pub fn new() -> Self {
 63        XMPPCodec {
 64            parser: xml::Parser::new(),
 65            root: None,
 66        }
 67    }
 68}
 69
 70impl Codec for XMPPCodec {
 71    type In = Packet;
 72    type Out = Packet;
 73
 74    fn decode(&mut self, buf: &mut EasyBuf) -> Result<Option<Self::In>, Error> {
 75        println!("XMPPCodec.decode {:?}", buf.len());
 76        let buf_len = buf.len();
 77        let chunk = buf.drain_to(buf_len);
 78        match from_utf8(chunk.as_slice()) {
 79            Ok(s) =>
 80                self.parser.feed_str(s),
 81            Err(e) =>
 82                return Err(Error::new(ErrorKind::InvalidInput, e)),
 83        }
 84
 85        let mut new_root = None;
 86        let mut result = None;
 87        for event in &mut self.parser {
 88            match self.root {
 89                None => {
 90                    // Expecting <stream:stream>
 91                    match event {
 92                        Ok(xml::Event::ElementStart(start_tag)) => {
 93                            self.root = Some(XMPPRoot::new(start_tag));
 94                            result = Some(Packet::StreamStart);
 95                            break
 96                        },
 97                        Err(e) => {
 98                            result = Some(Packet::Error(Box::new(e)));
 99                            break
100                        },
101                        _ =>
102                            (),
103                    }
104                }
105
106                Some(ref mut root) => {
107                    match root.handle_event(event) {
108                        None => (),
109                        Some(Ok(stanza)) => {
110                            println!("stanza: {}", stanza);
111                            result = Some(Packet::Stanza(stanza));
112                            break
113                        },
114                        Some(Err(e)) => {
115                            result = Some(Packet::Error(Box::new(e)));
116                            break
117                        }
118                    };
119                },
120            }
121
122            match new_root.take() {
123                None => (),
124                Some(root) => self.root = Some(root),
125            }
126        }
127
128        Ok(result)
129    }
130
131    fn encode(&mut self, msg: Self::Out, buf: &mut Vec<u8>) -> Result<(), Error> {
132        match msg {
133            Packet::StreamStart => {
134                let mut write = |s: &str| {
135                    buf.extend_from_slice(s.as_bytes());
136                };
137
138                write("<?xml version='1.0'?>\n");
139                write("<stream:stream");
140                write(" version='1.0'");
141                write(" to='spaceboyz.net'");
142                write(&format!(" xmlns='{}'", NS_CLIENT));
143                write(&format!(" xmlns:stream='{}'", NS_STREAMS));
144                write(">\n");
145
146                Ok(())
147            },
148            // TODO: Implement all
149            _ => Ok(())
150        }
151    }
152
153    fn decode_eof(&mut self, _buf: &mut EasyBuf) -> Result<Self::In, Error> {
154        Err(Error::from(ErrorKind::UnexpectedEof))
155    }
156}