echo_bot.rs

 1extern crate futures;
 2extern crate tokio_core;
 3extern crate tokio_xmpp;
 4extern crate jid;
 5extern crate xml;
 6
 7use tokio_core::reactor::Core;
 8use futures::{Future, Stream, Sink, future};
 9use tokio_xmpp::{Client, ClientEvent};
10
11fn main() {
12    let mut core = Core::new().unwrap();
13    let client = Client::new("astrobot@example.org", "", &core.handle()).unwrap();
14
15    let (sink, stream) = client.split();
16    let mut sink = Some(sink);
17    let mut send = move |stanza| {
18        sink = Some(
19            sink.take().
20                expect("sink")
21                .send(stanza)
22                .wait()
23                .expect("sink.send")
24        );
25    };
26    let done = stream.for_each(|event| {
27        let result: Box<Future<Item=(), Error=String>> = match event {
28            ClientEvent::Online => {
29                println!("Online!");
30
31                let presence = make_presence();
32                send(presence);
33                Box::new(
34                    future::ok(())
35                )
36            },
37            ClientEvent::Stanza(ref stanza)
38                if stanza.name == "message"
39                && stanza.get_attribute("type", None) != Some("error") =>
40            {
41                let from = stanza.get_attribute("from", None);
42                let body = stanza.get_child("body", Some("jabber:client"))
43                    .map(|el| el.content_str());
44
45                match (from.as_ref(), body) {
46                    (Some(from), Some(body)) => {
47                        let reply = make_reply(from, body);
48                        send(reply);
49                    },
50                    _ => (),
51                };
52                Box::new(future::ok(()))
53            },
54            _ => {
55                Box::new(future::ok(()))
56            },
57        };
58        result
59    });
60    
61    match core.run(done) {
62        Ok(_) => (),
63        Err(e) => {
64            println!("Fatal: {}", e);
65            ()
66        }
67    }
68}
69
70fn make_presence() -> xml::Element {
71    let mut presence = xml::Element::new("presence".to_owned(), None, vec![]);
72    presence.tag(xml::Element::new("status".to_owned(), None, vec![]))
73        .text("chat".to_owned());
74    presence.tag(xml::Element::new("show".to_owned(), None, vec![]))
75        .text("Echoing messages".to_owned());
76    presence
77}
78
79fn make_reply(to: &str, body: String) -> xml::Element {
80    let mut message = xml::Element::new(
81        "message".to_owned(),
82        None,
83        vec![("type".to_owned(), None, "chat".to_owned()),
84             ("to".to_owned(), None, to.to_owned())]
85    );
86    message.tag(xml::Element::new("body".to_owned(), None, vec![]))
87        .text(body);
88    message
89}