Skip to main content

AirLibrary/Client/AirClient/
DownloadUpdate.rs

1//! `AirClient::DownloadUpdate` - downloads an update package to disk via
2//! the Air daemon's `DownloaderService`. Uses the same `DownloadRequest`
3//! wire shape as [`AirClient::DownloadFile`] but routes via the
4//! `download_update` RPC so server-side metrics can attribute the bandwidth
5//! to update operations.
6
7use std::collections::HashMap;
8
9use tonic::Request;
10
11use crate::{
12	AirError,
13	Client::AirClient::{AirClient, FileInfo},
14	Vine::Generated::air::DownloadRequest,
15	dev_log,
16};
17
18impl AirClient {
19	/// Downloads an update package.
20	///
21	/// # Arguments
22	///
23	/// - `request_id` - opaque correlation id.
24	/// - `url` - HTTPS URL of the update package.
25	/// - `destination_path` - local filesystem path the package writes to.
26	/// - `checksum` - SHA-256 hex string; empty disables verification.
27	/// - `headers` - extra HTTP headers (e.g. `"Authorization"`).
28	pub async fn DownloadUpdate(
29		&self,
30
31		request_id:String,
32
33		url:String,
34
35		destination_path:String,
36
37		checksum:String,
38
39		headers:HashMap<String, String>,
40	) -> Result<FileInfo::Struct, AirError> {
41		dev_log!("grpc", "[AirClient] Downloading update from: {}", url);
42
43		let RequestPayload = DownloadRequest { request_id, url, destination_path, checksum, headers };
44
45		let Client = self
46			.Client()
47			.ok_or_else(|| AirError::Network("Air client not initialized".to_string()))?;
48
49		let mut ClientGuard = Client.lock().await;
50
51		match ClientGuard.download_update(Request::new(RequestPayload)).await {
52			Ok(Response) => {
53				let Response = Response.into_inner();
54
55				if Response.success {
56					dev_log!("grpc", "[AirClient] Update downloaded successfully to: {}", Response.file_path);
57
58					Ok(FileInfo::Struct {
59						file_path:Response.file_path,
60						file_size:Response.file_size,
61						checksum:Response.checksum,
62					})
63				} else {
64					dev_log!("grpc", "error: [AirClient] Update download failed: {}", Response.error);
65
66					Err(AirError::Network(Response.error))
67				}
68			},
69
70			Err(Status) => {
71				dev_log!("grpc", "error: [AirClient] Download update RPC error: {}", Status);
72
73				Err(AirError::Network(format!("Download update RPC error: {}", Status)))
74			},
75		}
76	}
77}