Skip to main content

AirLibrary/Client/AirClient/
DownloadStream.rs

1//! Wrapper for an asynchronous Air download stream.
2//!
3//! Adapts the tonic streaming API into a `next().await` iterator that
4//! yields [`DownloadStreamChunk::Struct`] items. Stream failures (HTTP/2
5//! frame errors, mid-stream disconnect) surface as [`AirError::Network`].
6
7use crate::{AirError, Client::AirClient::DownloadStreamChunk, Vine::Generated::air::DownloadStreamResponse, dev_log};
8
9pub struct Struct {
10	inner:tonic::codec::Streaming<DownloadStreamResponse>,
11}
12
13impl Struct {
14	pub fn new(Stream:tonic::codec::Streaming<DownloadStreamResponse>) -> Self { Self { inner:Stream } }
15
16	/// Returns the next chunk from the stream. `None` when the stream ends.
17	pub async fn next(&mut self) -> Option<Result<DownloadStreamChunk::Struct, AirError>> {
18		match futures_util::stream::StreamExt::next(&mut self.inner).await {
19			Some(Ok(Response)) => {
20				Some(Ok(DownloadStreamChunk::Struct {
21					data:Response.chunk,
22					total_size:Response.total_size,
23					downloaded:Response.downloaded,
24					completed:Response.completed,
25					error:Response.error,
26				}))
27			},
28
29			Some(Err(Error)) => {
30				dev_log!("grpc", "error: [DownloadStream] Stream error: {}", Error);
31
32				Some(Err(AirError::Network(format!("Stream error: {}", Error))))
33			},
34
35			None => None,
36		}
37	}
38}