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;
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>> =
28            if event.is_online() {
29                println!("Online!");
30
31                let presence = make_presence();
32                send(presence);
33                Box::new(
34                    future::ok(())
35                )
36            } else if let Some(stanza) = event.as_stanza() {
37                if stanza.name == "message" &&
38                    stanza.get_attribute("type", None) != Some("error") {
39                        let from = stanza.get_attribute("from", None);
40                        let body = stanza.get_child("body", Some("jabber:client"))
41                            .map(|el| el.content_str());
42
43                        match (from.as_ref(), body) {
44                            (Some(from), Some(body)) => {
45                                let reply = make_reply(from, body);
46                                send(reply);
47                            },
48                            _ => (),
49                        };
50                    }
51                Box::new(future::ok(()))
52            } else {
53                Box::new(future::ok(()))
54            };
55        result
56    });
57    
58    match core.run(done) {
59        Ok(_) => (),
60        Err(e) => {
61            println!("Fatal: {}", e);
62            ()
63        }
64    }
65}
66
67fn make_presence() -> xml::Element {
68    let mut presence = xml::Element::new("presence".to_owned(), None, vec![]);
69    presence.tag(xml::Element::new("status".to_owned(), None, vec![]))
70        .text("chat".to_owned());
71    presence.tag(xml::Element::new("show".to_owned(), None, vec![]))
72        .text("Echoing messages".to_owned());
73    presence
74}
75
76fn make_reply(to: &str, body: String) -> xml::Element {
77    let mut message = xml::Element::new(
78        "message".to_owned(),
79        None,
80        vec![("type".to_owned(), None, "chat".to_owned()),
81             ("to".to_owned(), None, to.to_owned())]
82    );
83    message.tag(xml::Element::new("body".to_owned(), None, vec![]))
84        .text(body);
85    message
86}