mod.rs

  1// Copyright (c) 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
  2//
  3// This Source Code Form is subject to the terms of the Mozilla Public
  4// License, v. 2.0. If a copy of the MPL was not distributed with this
  5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6
  7use crate::Event;
  8use futures::sync::mpsc;
  9use std::convert::TryFrom;
 10use std::str::FromStr;
 11use tokio_xmpp::Packet;
 12use xmpp_parsers::{
 13    Jid, BareJid,
 14    Element,
 15    ns,
 16    bookmarks2::{
 17        Autojoin,
 18        Conference,
 19    },
 20    pubsub::event::PubSubEvent,
 21    pubsub::pubsub::PubSub,
 22};
 23
 24#[cfg(feature = "avatars")]
 25pub(crate) mod avatar;
 26
 27pub(crate) fn handle_event(from: &Jid, elem: Element, mut tx: &mut mpsc::UnboundedSender<Packet>) -> impl IntoIterator<Item = Event> {
 28    let mut events = Vec::new();
 29    match PubSubEvent::try_from(elem) {
 30        Ok(PubSubEvent::PublishedItems { node, items }) => {
 31            match node.0 {
 32                #[cfg(feature = "avatars")]
 33                node if node == ns::AVATAR_METADATA => {
 34                    let new_events = avatar::handle_metadata_pubsub_event(&from, &mut tx, items);
 35                    events.extend(new_events);
 36                },
 37                node if node == ns::BOOKMARKS2 => {
 38                    // TODO: Check that our bare JID is the sender.
 39                    assert_eq!(items.len(), 1);
 40                    let item = items.clone().pop().unwrap();
 41                    let jid = BareJid::from_str(&item.id.clone().unwrap().0).unwrap();
 42                    let payload = item.payload.clone().unwrap();
 43                    match Conference::try_from(payload) {
 44                        Ok(conference) => {
 45                            if conference.autojoin == Autojoin::True {
 46                                events.push(Event::JoinRoom(jid, conference));
 47                            } else {
 48                                events.push(Event::LeaveRoom(jid));
 49                            }
 50                        },
 51                        Err(err) => println!("not bookmark: {}", err)
 52                    }
 53                },
 54                node => unimplemented!("node {}", node)
 55            }
 56        }
 57        Ok(PubSubEvent::RetractedItems { node, items }) => {
 58            match node.0 {
 59                node if node == ns::BOOKMARKS2 => {
 60                    // TODO: Check that our bare JID is the sender.
 61                    assert_eq!(items.len(), 1);
 62                    let item = items.clone().pop().unwrap();
 63                    let jid = BareJid::from_str(&item.0).unwrap();
 64                    events.push(Event::LeaveRoom(jid));
 65                },
 66                node => unimplemented!("node {}", node)
 67            }
 68        }
 69        Ok(PubSubEvent::Purge { node }) => {
 70            match node.0 {
 71                node if node == ns::BOOKMARKS2 => {
 72                    // TODO: Check that our bare JID is the sender.
 73                    events.push(Event::LeaveAllRooms);
 74                },
 75                node => unimplemented!("node {}", node)
 76            }
 77        }
 78        _ => unimplemented!()
 79    }
 80    events
 81}
 82
 83pub(crate) fn handle_iq_result(from: &Jid, elem: Element) -> impl IntoIterator<Item = Event> {
 84    let mut events = Vec::new();
 85    let pubsub = PubSub::try_from(elem).unwrap();
 86    if let PubSub::Items(items) = pubsub {
 87        match items.node.0.clone() {
 88            #[cfg(feature = "avatars")]
 89            node if node == ns::AVATAR_DATA => {
 90                let new_events = avatar::handle_data_pubsub_iq(&from, &items);
 91                events.extend(new_events);
 92            },
 93            node if node == ns::BOOKMARKS2 => {
 94                events.push(Event::LeaveAllRooms);
 95                for item in items.items {
 96                    let item = item.0;
 97                    let jid = BareJid::from_str(&item.id.clone().unwrap().0).unwrap();
 98                    let payload = item.payload.clone().unwrap();
 99                    match Conference::try_from(payload) {
100                        Ok(conference) => {
101                            if let Autojoin::True = conference.autojoin {
102                                events.push(Event::JoinRoom(jid, conference));
103                            }
104                        },
105                        Err(err) => panic!("Wrong payload type in bookmarks 2 item: {}", err),
106                    }
107                }
108            },
109            _ => unimplemented!()
110        }
111    }
112    events
113}