xmpp_codec.rs

  1use std;
  2use std::fmt::Write;
  3use std::str::from_utf8;
  4use std::io::{Error, ErrorKind};
  5use std::collections::HashMap;
  6use tokio_io::codec::{Framed, Encoder, Decoder};
  7use xml;
  8use bytes::*;
  9
 10const NS_XMLNS: &'static str = "http://www.w3.org/2000/xmlns/";
 11const NS_STREAMS: &'static str = "http://etherx.jabber.org/streams";
 12const NS_CLIENT: &'static str = "jabber:client";
 13
 14struct XMPPRoot {
 15    builder: xml::ElementBuilder,
 16    pub attributes: HashMap<(String, Option<String>), String>,
 17}
 18
 19impl XMPPRoot {
 20    fn new(root: xml::StartTag) -> Self {
 21        let mut builder = xml::ElementBuilder::new();
 22        let mut attributes = HashMap::new();
 23        println!("root attributes: {:?}", root.attributes);
 24        for (name_ns, value) in root.attributes {
 25            match name_ns {
 26                (ref name, None) if name == "xmlns" =>
 27                    builder.set_default_ns(value),
 28                (ref prefix, Some(ref ns)) if ns == NS_XMLNS =>
 29                    builder.define_prefix(prefix.to_owned(), value),
 30                _ => {
 31                    attributes.insert(name_ns, value);
 32                },
 33            }
 34        }
 35
 36        XMPPRoot {
 37            builder: builder,
 38            attributes: attributes,
 39        }
 40    }
 41
 42    fn handle_event(&mut self, event: Result<xml::Event, xml::ParserError>)
 43                    -> Option<Result<xml::Element, xml::BuilderError>> {
 44        self.builder.handle_event(event)
 45    }
 46}
 47
 48#[derive(Debug)]
 49pub enum Packet {
 50    Error(Box<std::error::Error>),
 51    StreamStart,
 52    Stanza(xml::Element),
 53    StreamEnd,
 54}
 55
 56pub type XMPPStream<T> = Framed<T, XMPPCodec>;
 57
 58pub struct XMPPCodec {
 59    parser: xml::Parser,
 60    root: Option<XMPPRoot>,
 61}
 62
 63impl XMPPCodec {
 64    pub fn new() -> Self {
 65        XMPPCodec {
 66            parser: xml::Parser::new(),
 67            root: None,
 68        }
 69    }
 70}
 71
 72impl Decoder for XMPPCodec {
 73    type Item = Packet;
 74    type Error = Error;
 75
 76    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
 77        println!("XMPPCodec.decode {:?}", buf.len());
 78        match from_utf8(buf.take().as_ref()) {
 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: Option<XMPPRoot> = 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 decode_eof(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Error> {
132        self.decode(buf)
133    }
134}
135
136impl Encoder for XMPPCodec {
137    type Item = Packet;
138    type Error = Error;
139
140    fn encode(&mut self, item: Self::Item, dst: &mut BytesMut) -> Result<(), Self::Error> {
141        match item {
142            Packet::StreamStart => {
143                write!(dst,
144                       "<?xml version='1.0'?>\n
145<stream:stream version='1.0' to='spaceboyz.net' xmlns='{}' xmlns:stream='{}'>\n",
146                       NS_CLIENT, NS_STREAMS)
147                    .map_err(|_| Error::from(ErrorKind::WriteZero))
148            },
149            // TODO: Implement all
150            _ => Ok(())
151        }
152    }
153}