tokio_xmpp/xmlstream/
responder.rs1use core::pin::Pin;
8use std::borrow::Cow;
9use std::io;
10
11use futures::SinkExt;
12
13use tokio::io::{AsyncBufRead, AsyncWrite};
14
15use xmpp_parsers::stream_features::StreamFeatures;
16
17use xso::{AsXml, FromXml};
18
19use super::{
20 common::{RawXmlStream, StreamHeader},
21 XmlStream,
22};
23
24pub struct AcceptedStream<Io> {
28 pub(super) stream: RawXmlStream<Io>,
29 pub(super) header: StreamHeader<'static>,
30}
31
32impl<Io> AcceptedStream<Io> {
33 pub fn header(&self) -> StreamHeader<'_> {
35 StreamHeader {
36 from: self.header.from.as_ref().map(|x| Cow::Borrowed(&**x)),
37 to: self.header.to.as_ref().map(|x| Cow::Borrowed(&**x)),
38 id: self.header.id.as_ref().map(|x| Cow::Borrowed(&**x)),
39 }
40 }
41
42 pub fn take_header(&mut self) -> StreamHeader<'static> {
44 self.header.take()
45 }
46}
47
48impl<Io: AsyncBufRead + AsyncWrite + Unpin> AcceptedStream<Io> {
49 pub async fn send_header(
54 self,
55 header: StreamHeader<'_>,
56 ) -> io::Result<PendingFeaturesSend<Io>> {
57 let Self {
58 mut stream,
59 header: _,
60 } = self;
61
62 header.send(Pin::new(&mut stream)).await?;
63 Ok(PendingFeaturesSend { stream })
64 }
65}
66
67pub struct PendingFeaturesSend<Io> {
72 pub(super) stream: RawXmlStream<Io>,
73}
74
75impl<Io: AsyncBufRead + AsyncWrite + Unpin> PendingFeaturesSend<Io> {
76 pub async fn send_features<T: FromXml + AsXml>(
82 self,
83 features: &'_ StreamFeatures,
84 ) -> io::Result<XmlStream<Io, T>> {
85 let Self { mut stream } = self;
86 Pin::new(&mut stream).start_send_xso(features)?;
87 stream.flush().await?;
88
89 Ok(XmlStream::wrap(stream))
90 }
91}