use std::{fmt, io}; use futures::prelude::*; use futures::stream::BoxStream; use imap_codec::codec::Encode; use imap_codec::types::response::{Data as ImapData, Status as ImapStatus}; use super::Status; pub enum Body { Once(Vec), Stream(BoxStream<'static, Data>), } impl Body { pub fn from_stream + Send + 'static>(stream: St) -> Self { Body::Stream(stream.boxed()) } } impl Body { pub(crate) fn into_stream(self) -> BoxStream<'static, Data> { match self { Body::Once(data) => futures::stream::iter(data).boxed(), Body::Stream(stream) => stream, } } } impl FromIterator for Body { fn from_iter>(iter: T) -> Self { Body::Once(Vec::from_iter(iter)) } } impl FromIterator for Body { fn from_iter>(iter: T) -> Self { Body::from_iter(iter.into_iter().map(Data::Data)) } } impl From> for Body { fn from(body: Vec) -> Self { Body::from_iter(body) } } impl From> for Body { fn from(data: Vec) -> Self { Body::from_iter(data) } } impl From for Body { fn from(data: ImapData) -> Self { Body::from_iter([data]) } } impl fmt::Debug for Body { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Body::Once(ref data) => f.debug_struct("Body::Once").field("data", data).finish(), Body::Stream(_) => f.debug_struct("Body::Stream").finish_non_exhaustive(), } } } #[derive(Debug, Clone)] pub enum Data { Data(ImapData), Status(ImapStatus), Close, } impl Encode for Data { fn encode(&self, writer: &mut impl io::Write) -> std::io::Result<()> { match self { Data::Data(ref data) => data.encode(writer), Data::Status(ref status) => status.encode(writer), Data::Close => Ok(()), } } } impl From for Data { fn from(data: ImapData) -> Self { Data::Data(data) } } impl From for Data { fn from(status: ImapStatus) -> Self { Data::Status(status) } } impl From for Data { fn from(status: Status) -> Self { status.into_imap(None).into() } }