stanzas.rs
use std::collections::BTreeSet;
use tokio_xmpp::Stanza;
use xmpp_parsers::disco::{DiscoInfoQuery, DiscoInfoResult, DiscoItemsResult, Identity};
use xmpp_parsers::iq::Iq;
use xmpp_parsers::message::{Message, MessageType};
use xmpp_parsers::ping::Ping;
use xmpp_parsers::presence::{Presence, Show as PresenceShow, Type as PresenceType};
use xmpp_parsers::roster::{Item, Roster};
use xmpp_parsers::stanza_error::{DefinedCondition, ErrorType, StanzaError};
use xmpp_parsers::version::VersionResult;
use xmpp_parsers::{jid, minidom::Element};
pub fn make_presence(id: String, show: Option<PresenceShow>, text: String) -> Stanza {
let mut presence = Presence::new(PresenceType::None);
presence.id = Some(id);
presence.show = show;
presence
.statuses
.insert(xmpp_parsers::message::Lang(String::from("en")), text);
Stanza::Presence(presence)
}
pub fn make_get_roster(id: &str) -> Stanza {
Stanza::Iq(Iq::from_get(
id,
Roster {
items: vec![],
ver: None,
},
))
}
pub fn make_add_roster(id: &str, jid: jid::BareJid) -> Stanza {
Stanza::Iq(Iq::from_set(
id,
Roster {
items: vec![Item {
jid,
name: None,
subscription: xmpp_parsers::roster::Subscription::None,
ask: xmpp_parsers::roster::Ask::None,
groups: vec![],
approved: None,
}],
ver: None,
},
))
}
pub fn make_roster_push_answer(id: String, from: jid::FullJid, to: Option<jid::Jid>) -> Iq {
let mut answer = Iq::from_result(id, None as Option<Roster>).with_from(jid::Jid::from(from));
if let Some(to) = to {
answer = answer.with_to(to);
}
answer
}
pub fn make_ask_subscribe(id: String, jid: jid::Jid) -> Stanza {
let mut presence = Presence::new(PresenceType::Subscribe);
presence.id = Some(id);
presence.to = Some(jid);
Stanza::Presence(presence)
}
pub fn make_allow_subscribe(id: String, jid: jid::Jid) -> Stanza {
let mut presence = Presence::new(PresenceType::Subscribed);
presence.id = Some(id);
presence.to = Some(jid);
Stanza::Presence(presence)
}
pub fn make_chat_message(id: String, jid: jid::Jid, text: String) -> Stanza {
let mut message = Message::new(Some(jid));
message.id = Some(xmpp_parsers::message::Id(id));
message
.bodies
.insert(xmpp_parsers::message::Lang::new(), text);
message.type_ = MessageType::Chat;
message
.payloads
.push(xmpp_parsers::receipts::Request {}.into());
Stanza::Message(message)
}
pub fn make_muc_presence(
id: &str,
from: jid::FullJid,
to: jid::FullJid,
show: Option<PresenceShow>,
text: Option<String>,
) -> Stanza {
let mut presence = Presence::new(PresenceType::None);
presence.from = Some(jid::Jid::from(from));
presence.to = Some(jid::Jid::from(to));
presence.id = Some(id.to_string());
presence.show = show;
if let Some(text) = text {
presence
.statuses
.insert(xmpp_parsers::message::Lang(String::from("en")), text);
}
presence.add_payload(xmpp_parsers::muc::Muc::new());
Stanza::Presence(presence)
}
pub fn make_muc_message(id: String, to: jid::FullJid, text: String) -> Stanza {
let mut message =
Message::groupchat(jid::Jid::from(to)).with_body(xmpp_parsers::message::Lang::new(), text);
message.id = Some(xmpp_parsers::message::Id(id));
Stanza::Message(message)
}
pub fn make_muc_presence_leave(from: jid::Jid, to: jid::Jid) -> Element {
let mut presence = Presence::new(PresenceType::Unavailable);
presence.from = Some(from);
presence.to = Some(to);
presence.into()
}
pub fn make_ping(id: &str, from: jid::Jid, to: Option<jid::BareJid>) -> Stanza {
let ping = Iq::from_get(id, Ping)
.with_to(jid::Jid::from(to.unwrap_or_else(|| {
jid::BareJid::from_parts(None, from.domain())
})))
.with_from(from);
Stanza::Iq(ping)
}
pub fn make_pong(id: String, from: jid::FullJid, to: Option<jid::Jid>) -> Iq {
let mut pong = Iq::from_result(id, None as Option<Roster>).with_from(jid::Jid::from(from));
if let Some(to) = to {
pong = pong.with_to(to);
}
pong
}
pub fn make_version(id: String, from: jid::FullJid, to: Option<jid::Jid>) -> Iq {
let mut version = Iq::from_result(
id,
Some(VersionResult {
name: "SendXmppDRust".to_string(),
version: "0.1.0".to_string(),
os: None,
}),
)
.with_from(jid::Jid::from(from));
if let Some(to) = to {
version = version.with_to(to);
}
version
}
pub fn make_iq_unsupported_error(id: String, from: jid::FullJid, to: Option<jid::Jid>) -> Iq {
let mut error = Iq::from_error(
id,
StanzaError {
type_: ErrorType::Cancel,
by: Some(jid::Jid::from(from.clone())),
defined_condition: DefinedCondition::ServiceUnavailable,
texts: std::collections::BTreeMap::new(),
other: None,
},
)
.with_from(jid::Jid::from(from));
if let Some(to) = to {
error = error.with_to(to);
}
error
}
pub fn make_disco_info_result(id: String, from: jid::FullJid, to: Option<jid::Jid>) -> Iq {
let mut result = Iq::from_result(
id,
Some(DiscoInfoResult {
node: None,
identities: vec![Identity {
category: "client".to_string(),
type_: "bot".to_string(),
name: None,
lang: None,
}],
features: {
let mut features = BTreeSet::new();
features.insert("http://jabber.org/protocol/disco#info".to_string());
features.insert("urn:xmpp:ping".to_string());
features.insert("http://jabber.org/protocol/commands".to_string());
features
},
extensions: vec![],
}),
)
.with_from(jid::Jid::from(from));
if let Some(to) = to {
result = result.with_to(to);
}
result
}
pub fn make_disco_items_result(id: String, from: jid::FullJid, to: Option<jid::Jid>) -> Iq {
let mut result = Iq::from_result(
id,
Some(DiscoItemsResult {
node: None,
items: vec![],
rsm: None,
}),
)
.with_from(jid::Jid::from(from));
if let Some(to) = to {
result = result.with_to(to);
}
result
}
pub fn make_disco_items_commands(id: String, from: jid::FullJid, to: Option<jid::Jid>) -> Iq {
let mut result = Iq::from_result(
id,
Some(DiscoItemsResult {
node: Some("http://jabber.org/protocol/commands".to_string()),
items: vec![],
rsm: None,
}),
)
.with_from(jid::Jid::from(from));
if let Some(to) = to {
result = result.with_to(to);
}
result
}
pub fn make_disco_get(id: String, from: jid::Jid, to: jid::Jid) -> Stanza {
let get = Iq::from_get(id, DiscoInfoQuery { node: None })
.with_to(to)
.with_from(from);
Stanza::Iq(get)
}