1use std::collections::HashMap;
2use futures::*;
3use tokio_io::{AsyncRead, AsyncWrite};
4use tokio_io::codec::Framed;
5use xml;
6use jid::Jid;
7
8use xmpp_codec::*;
9use stream_start::*;
10
11pub const NS_XMPP_STREAM: &str = "http://etherx.jabber.org/streams";
12
13pub struct XMPPStream<S> {
14 pub jid: Jid,
15 pub stream: Framed<S, XMPPCodec>,
16 pub stream_attrs: HashMap<String, String>,
17 pub stream_features: xml::Element,
18}
19
20impl<S: AsyncRead + AsyncWrite> XMPPStream<S> {
21 pub fn new(jid: Jid,
22 stream: Framed<S, XMPPCodec>,
23 stream_attrs: HashMap<String, String>,
24 stream_features: xml::Element) -> Self {
25 XMPPStream { jid, stream, stream_attrs, stream_features }
26 }
27
28 pub fn from_stream(stream: S, jid: Jid) -> StreamStart<S> {
29 let xmpp_stream = AsyncRead::framed(stream, XMPPCodec::new());
30 StreamStart::from_stream(xmpp_stream, jid)
31 }
32
33 pub fn into_inner(self) -> S {
34 self.stream.into_inner()
35 }
36
37 pub fn restart(self) -> StreamStart<S> {
38 Self::from_stream(self.stream.into_inner(), self.jid)
39 }
40}
41
42/// Proxy to self.stream
43impl<S: AsyncWrite> Sink for XMPPStream<S> {
44 type SinkItem = <Framed<S, XMPPCodec> as Sink>::SinkItem;
45 type SinkError = <Framed<S, XMPPCodec> as Sink>::SinkError;
46
47 fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
48 self.stream.start_send(item)
49 }
50
51 fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
52 self.stream.poll_complete()
53 }
54}
55
56/// Proxy to self.stream
57impl<S: AsyncRead> Stream for XMPPStream<S> {
58 type Item = <Framed<S, XMPPCodec> as Stream>::Item;
59 type Error = <Framed<S, XMPPCodec> as Stream>::Error;
60
61 fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
62 self.stream.poll()
63 }
64}