kernel/install/event.rs
1//! The progress and event types an install emits.
2
3use serde::{Deserialize, Serialize};
4
5/// Download progress for an install: bytes so far, the total (when known), and
6/// which file is in flight.
7///
8/// Serializable because a detached pull writes it into its `status.json`, which
9/// is the only way an attached client learns how far along the transfer is.
10#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
11pub struct InstallProgress {
12 /// Bytes downloaded so far.
13 #[serde(default)]
14 pub bytes_downloaded: i64,
15 /// The total to download, if known.
16 #[serde(skip_serializing_if = "Option::is_none", default)]
17 pub total_bytes: Option<i64>,
18 /// Whether `total_bytes` is a partial/growing estimate (so no fraction).
19 #[serde(default)]
20 pub total_is_partial: bool,
21 /// The file currently downloading, if any.
22 #[serde(skip_serializing_if = "Option::is_none", default)]
23 pub current_file: Option<String>,
24}
25
26impl InstallProgress {
27 /// The completed fraction in `[0, 1]`, or `None` when the total is unknown,
28 /// zero, or only a partial estimate.
29 pub fn fraction(&self) -> Option<f64> {
30 let total = self.total_bytes?;
31 if total <= 0 || self.total_is_partial {
32 return None;
33 }
34 Some((self.bytes_downloaded as f64 / total as f64).clamp(0.0, 1.0))
35 }
36}
37
38/// A lifecycle event for an install job.
39#[derive(Debug, Clone, PartialEq, Eq, Hash)]
40pub enum InstallEvent {
41 /// Waiting to start.
42 Queued,
43 /// Resolving the plan before transfer.
44 Preparing,
45 /// A human-readable status line.
46 Status(String),
47 /// Download progress.
48 Progress(InstallProgress),
49 /// Completed successfully.
50 Done,
51 /// Failed, with a message.
52 Failed {
53 /// Why it failed.
54 message: String,
55 },
56 /// Cancelled by the user.
57 Cancelled,
58}
59
60impl InstallEvent {
61 /// Whether this event ends the job (done/failed/cancelled).
62 pub fn is_terminal(&self) -> bool {
63 matches!(
64 self,
65 InstallEvent::Done | InstallEvent::Failed { .. } | InstallEvent::Cancelled
66 )
67 }
68}
69
70/// What a provider's transfer emits while running (before the terminal event is
71/// synthesized by the install service).
72#[derive(Debug, Clone, PartialEq, Eq, Hash)]
73pub enum InstallStreamEvent {
74 /// A status line.
75 Status(String),
76 /// Download progress.
77 Progress(InstallProgress),
78}