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 super::Agent;
  8use crate::Event;
  9use std::convert::TryFrom;
 10use std::str::FromStr;
 11use xmpp_parsers::{
 12    bookmarks2::{Autojoin, Conference},
 13    ns,
 14    pubsub::event::PubSubEvent,
 15    pubsub::pubsub::PubSub,
 16    BareJid, Element, Jid,
 17};
 18
 19#[cfg(feature = "avatars")]
 20pub(crate) mod avatar;
 21
 22pub(crate) async fn handle_event(from: &Jid, elem: Element, agent: &mut Agent) -> Vec<Event> {
 23    let mut events = Vec::new();
 24    let event = PubSubEvent::try_from(elem);
 25    trace!("PubSub event: {:#?}", event);
 26    match event {
 27        Ok(PubSubEvent::PublishedItems { node, items }) => {
 28            match node.0 {
 29                #[cfg(feature = "avatars")]
 30                ref node if node == ns::AVATAR_METADATA => {
 31                    let new_events =
 32                        avatar::handle_metadata_pubsub_event(&from, agent, items).await;
 33                    events.extend(new_events);
 34                }
 35                ref node if node == ns::BOOKMARKS2 => {
 36                    // TODO: Check that our bare JID is the sender.
 37                    assert_eq!(items.len(), 1);
 38                    let item = items.clone().pop().unwrap();
 39                    let jid = BareJid::from_str(&item.id.clone().unwrap().0).unwrap();
 40                    let payload = item.payload.clone().unwrap();
 41                    match Conference::try_from(payload) {
 42                        Ok(conference) => {
 43                            if conference.autojoin == Autojoin::True {
 44                                events.push(Event::JoinRoom(jid, conference));
 45                            } else {
 46                                events.push(Event::LeaveRoom(jid));
 47                            }
 48                        }
 49                        Err(err) => println!("not bookmark: {}", err),
 50                    }
 51                }
 52                ref node => unimplemented!("node {}", node),
 53            }
 54        }
 55        Ok(PubSubEvent::RetractedItems { node, items }) => {
 56            match node.0 {
 57                ref node if node == ns::BOOKMARKS2 => {
 58                    // TODO: Check that our bare JID is the sender.
 59                    assert_eq!(items.len(), 1);
 60                    let item = items.clone().pop().unwrap();
 61                    let jid = BareJid::from_str(&item.0).unwrap();
 62                    events.push(Event::LeaveRoom(jid));
 63                }
 64                ref node => unimplemented!("node {}", node),
 65            }
 66        }
 67        Ok(PubSubEvent::Purge { node }) => {
 68            match node.0 {
 69                ref node if node == ns::BOOKMARKS2 => {
 70                    // TODO: Check that our bare JID is the sender.
 71                    events.push(Event::LeaveAllRooms);
 72                }
 73                ref node => unimplemented!("node {}", node),
 74            }
 75        }
 76        _ => unimplemented!(),
 77    }
 78    events
 79}
 80
 81pub(crate) fn handle_iq_result(from: &Jid, elem: Element) -> impl IntoIterator<Item = Event> {
 82    let mut events = Vec::new();
 83    let pubsub = PubSub::try_from(elem).unwrap();
 84    trace!("PubSub: {:#?}", pubsub);
 85    if let PubSub::Items(items) = pubsub {
 86        match items.node.0.clone() {
 87            #[cfg(feature = "avatars")]
 88            ref node if node == ns::AVATAR_DATA => {
 89                let new_events = avatar::handle_data_pubsub_iq(&from, &items);
 90                events.extend(new_events);
 91            }
 92            ref node if node == ns::BOOKMARKS2 => {
 93                events.push(Event::LeaveAllRooms);
 94                for item in items.items {
 95                    let item = item.0;
 96                    let jid = BareJid::from_str(&item.id.clone().unwrap().0).unwrap();
 97                    let payload = item.payload.clone().unwrap();
 98                    match Conference::try_from(payload) {
 99                        Ok(conference) => {
100                            if let Autojoin::True = conference.autojoin {
101                                events.push(Event::JoinRoom(jid, conference));
102                            }
103                        }
104                        Err(err) => panic!("Wrong payload type in bookmarks 2 item: {}", err),
105                    }
106                }
107            }
108            _ => unimplemented!(),
109        }
110    }
111    events
112}