Skip to main content

Mountain/Air/AirClient/
DownloadStream.rs

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