Skip to main content

Mountain/Air/AirClient/
DownloadStream.rs

1
2//! Wrapper for an asynchronous Air download stream. Adapts the tonic
3//! streaming API into a `next().await` iterator that yields
4//! `DownloadStreamChunk::Struct` items. Cfg-gated on `AirIntegration`
5//! because the inner type lives in `AirLibrary::Vine::Generated::air`.
6
7#[cfg(feature = "AirIntegration")]
8use CommonLibrary::Error::CommonError::CommonError;
9
10#[cfg(feature = "AirIntegration")]
11use crate::{Air::AirClient::DownloadStreamChunk, dev_log};
12
13#[cfg(feature = "AirIntegration")]
14pub struct Struct {
15	inner:tonic::codec::Streaming<AirLibrary::Vine::Generated::air::DownloadStreamResponse>,
16}
17
18#[cfg(feature = "AirIntegration")]
19impl Struct {
20	pub fn new(Stream:tonic::codec::Streaming<AirLibrary::Vine::Generated::air::DownloadStreamResponse>) -> Self {
21		Self { inner:Stream }
22	}
23
24	/// Returns the next chunk from the stream. `None` when the stream ends.
25	pub async fn next(&mut self) -> Option<Result<DownloadStreamChunk::Struct, CommonError>> {
26		match futures_util::stream::StreamExt::next(&mut self.inner).await {
27			Some(Ok(Response)) => {
28				Some(Ok(DownloadStreamChunk::Struct {
29					data:Response.chunk,
30					total_size:Response.total_size,
31					downloaded:Response.downloaded,
32					completed:Response.completed,
33					error:Response.error,
34				}))
35			},
36
37			Some(Err(Error)) => {
38				dev_log!("grpc", "error: [DownloadStream] Stream error: {}", Error);
39
40				Some(Err(CommonError::IPCError { Description:format!("Stream error: {}", Error) }))
41			},
42
43			None => None,
44		}
45	}
46}