@@ -13,6 +13,8 @@ XXXX-YY-ZZ RELEASER <admin@example.com>
not the other way around (!421)
- `AsyncClient::new` automatically reconnects by default (!436)
- `AsyncClient::poll_next` properly closes stream with `Poll::Ready(None)` when disconnecting without auto reconnect (!436)
+ - remove `tokio_xmpp::SimpleClient` because it was not widely used, and not well documented ; if you need it,
+ please let us know and it will be reintegrated (!428)
Version 4.0.0:
2024-07-26 Maxime “pep” Buquet <pep@bouah.net>
@@ -1,38 +0,0 @@
-use std::env::args;
-use std::io::{stdin, Read};
-use std::process::exit;
-use std::str::FromStr;
-use tokio_xmpp::SimpleClient as Client;
-use xmpp_parsers::jid::Jid;
-use xmpp_parsers::message::{Body, Message};
-
-#[tokio::main]
-async fn main() {
- env_logger::init();
-
- let args: Vec<String> = args().collect();
- if args.len() != 4 {
- println!("Usage: {} <jid> <password> <recipient>", args[0]);
- exit(1);
- }
- // Configuration
- let jid = &args[1];
- let password = &args[2];
- let recipient = Jid::from_str(&args[3]).unwrap();
-
- // Client instance
- let mut client = Client::new(jid, password.to_owned()).await.unwrap();
-
- // Read from stdin
- println!("Client connected, type message and submit with Ctrl-D");
- let mut body = String::new();
- stdin().lock().read_to_string(&mut body).unwrap();
-
- // Send message
- let mut message = Message::new(Some(recipient));
- message.bodies.insert(String::new(), Body(body.to_owned()));
- client.send_stanza(message).await.unwrap();
-
- // Close client connection
- client.end().await.unwrap();
-}
@@ -1,143 +0,0 @@
-use futures::{sink::SinkExt, Sink, Stream};
-use minidom::Element;
-use std::pin::Pin;
-#[cfg(feature = "starttls")]
-use std::str::FromStr;
-use std::task::{Context, Poll};
-use tokio_stream::StreamExt;
-use xmpp_parsers::{jid::Jid, ns, stream_features::StreamFeatures};
-
-use crate::connect::ServerConnector;
-#[cfg(feature = "starttls")]
-use crate::starttls::ServerConfig;
-use crate::xmpp_codec::Packet;
-use crate::xmpp_stream::{add_stanza_id, XMPPStream};
-use crate::Error;
-
-use super::connect::client_login;
-
-/// A simple XMPP client connection
-///
-/// This implements the `futures` crate's [`Stream`](#impl-Stream) and
-/// [`Sink`](#impl-Sink<Packet>) traits.
-pub struct Client<C: ServerConnector> {
- stream: XMPPStream<C::Stream>,
-}
-
-#[cfg(feature = "starttls")]
-impl Client<ServerConfig> {
- /// Start a new XMPP client and wait for a usable session
- pub async fn new<P: Into<String>>(jid: &str, password: P) -> Result<Self, Error> {
- let jid = Jid::from_str(jid)?;
- Self::new_with_jid(jid, password.into()).await
- }
-
- /// Start a new client given that the JID is already parsed.
- pub async fn new_with_jid(jid: Jid, password: String) -> Result<Self, Error> {
- Self::new_with_jid_connector(ServerConfig::UseSrv, jid, password).await
- }
-}
-
-impl<C: ServerConnector> Client<C> {
- /// Start a new client given that the JID is already parsed.
- pub async fn new_with_jid_connector(
- connector: C,
- jid: Jid,
- password: String,
- ) -> Result<Self, Error> {
- let stream = client_login(connector, jid, password).await?;
- Ok(Client { stream })
- }
-
- /// Get direct access to inner XMPP Stream
- pub fn into_inner(self) -> XMPPStream<C::Stream> {
- self.stream
- }
-
- /// Get the client's bound JID (the one reported by the XMPP
- /// server).
- pub fn bound_jid(&self) -> &Jid {
- &self.stream.jid
- }
-
- /// Send stanza
- pub async fn send_stanza<E>(&mut self, stanza: E) -> Result<(), Error>
- where
- E: Into<Element>,
- {
- self.send(Packet::Stanza(add_stanza_id(
- stanza.into(),
- ns::JABBER_CLIENT,
- )))
- .await
- }
-
- /// Get the stream features (`<stream:features/>`) of the underlying stream
- pub fn get_stream_features(&self) -> &StreamFeatures {
- &self.stream.stream_features
- }
-
- /// End connection by sending `</stream:stream>`
- ///
- /// You may expect the server to respond with the same. This
- /// client will then drop its connection.
- pub async fn end(mut self) -> Result<(), Error> {
- self.send(Packet::StreamEnd).await?;
-
- // Wait for stream end from server
- while let Some(Ok(_)) = self.next().await {}
-
- Ok(())
- }
-}
-
-/// Incoming XMPP events
-///
-/// In an `async fn` you may want to use this with `use
-/// futures::stream::StreamExt;`
-impl<C: ServerConnector> Stream for Client<C> {
- type Item = Result<Element, Error>;
-
- /// Low-level read on the XMPP stream
- fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
- loop {
- match Pin::new(&mut self.stream).poll_next(cx) {
- Poll::Pending => return Poll::Pending,
- Poll::Ready(Some(Ok(Packet::Stanza(stanza)))) => {
- return Poll::Ready(Some(Ok(stanza)))
- }
- Poll::Ready(Some(Ok(Packet::Text(_)))) => {
- // Ignore, retry
- }
- Poll::Ready(_) =>
- // Unexpected and errors, just end
- {
- return Poll::Ready(None)
- }
- }
- }
- }
-}
-
-/// Outgoing XMPP packets
-///
-/// See `send_stanza()` for an `async fn`
-impl<C: ServerConnector> Sink<Packet> for Client<C> {
- type Error = Error;
-
- fn start_send(mut self: Pin<&mut Self>, item: Packet) -> Result<(), Self::Error> {
- Pin::new(&mut self.stream).start_send(item)
- }
-
- fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
- Pin::new(&mut self.stream).poll_ready(cx)
- }
-
- fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
- Pin::new(&mut self.stream).poll_flush(cx)
- }
-
- fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
- Pin::new(&mut self.stream).poll_close(cx)
- }
-}
@@ -35,7 +35,6 @@ pub mod xmpp_stream;
pub use client::{
async_client::{Client as AsyncClient, Config as AsyncConfig},
- simple_client::Client as SimpleClient,
};
mod component;
pub use crate::component::Component;
@@ -32,7 +32,7 @@ use crate::{
error::{Error, ProtocolError},
xmpp_codec::Packet,
xmpp_stream::XMPPStream,
- AsyncClient, SimpleClient,
+ AsyncClient,
};
use self::error::Error as StartTlsError;
@@ -41,8 +41,6 @@ pub mod error;
/// AsyncClient that connects over StartTls
pub type StartTlsAsyncClient = AsyncClient<ServerConfig>;
-/// SimpleClient that connects over StartTls
-pub type StartTlsSimpleClient = SimpleClient<ServerConfig>;
/// StartTLS XMPP server connection configuration
#[derive(Clone, Debug)]