mutant_lib/events.rs
1use crate::error::Error;
2use futures::future::BoxFuture;
3use serde::{Deserialize, Serialize};
4
5/// Events emitted during the 'put' (store) operation.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub enum PutEvent {
8 /// Indicates that the allocator needs to reserve new scratchpads.
9 ReservingScratchpads { needed: u64 },
10 /// Indicates the start of the reservation process for a batch of pads.
11 ReservingPads { count: u64 },
12 /// Reports the result of reserving a single pad within a batch.
13 PadReserved {
14 index: u64,
15 total: u64,
16 result: Result<(), String>, // Ok(()) on success, Err(error_string) on failure
17 },
18 /// Prompts the caller (e.g., the binary) to confirm the reservation.
19 /// The callback should return `Ok(true)` to proceed, `Ok(false)` to cancel.
20 ConfirmReservation {
21 needed: u64,
22 data_size: u64,
23 total_space: u64,
24 free_space: u64,
25 current_scratchpads: usize,
26 estimated_cost: Option<String>,
27 },
28 /// Reports progress during scratchpad reservation.
29 ReservationProgress { current: u64, total: u64 },
30 /// Indicates that the data upload process is starting.
31 StartingUpload { total_bytes: u64 },
32 /// Reports progress during data upload.
33 UploadProgress {
34 bytes_written: u64,
35 total_bytes: u64,
36 },
37 /// Indicates that the data upload process has finished.
38 UploadFinished,
39 /// Indicates the entire store operation (allocation, write, metadata update) is complete.
40 StoreComplete,
41 /// Indicates that a single scratchpad's worth of data has been successfully uploaded.
42 ScratchpadUploadComplete { index: u64, total: u64 },
43 /// Indicates that a single scratchpad has been fully committed/finalized after upload.
44 ScratchpadCommitComplete { index: u64, total: u64 },
45}
46
47/// Type alias for the callback function used during the 'put' operation.
48/// Uses `async FnMut` which requires the `async_fn_in_trait` feature.
49/// It returns a `BoxFuture` to handle the async nature in a trait object.
50pub type PutCallback =
51 Box<dyn FnMut(PutEvent) -> BoxFuture<'static, Result<bool, Error>> + Send + Sync>;
52
53#[inline]
54pub async fn invoke_callback(
55 callback: &mut Option<PutCallback>,
56 event: PutEvent,
57) -> Result<(), Error> {
58 if let Some(cb) = callback {
59 let fut = cb(event);
60 match fut.await {
61 Ok(true) => Ok(()),
62 Ok(false) => Err(Error::OperationCancelled),
63 Err(e) => Err(e),
64 }
65 } else {
66 Ok(())
67 }
68}
69
70/// Events emitted during the library initialization, primarily for first-run setup.
71#[derive(Debug, Clone)]
72pub enum InitProgressEvent {
73 /// Starting the initialization process.
74 Starting { total_steps: u64 },
75 /// Progress update for a specific step.
76 Step { step: u64, message: String },
77 /// Initialization completed successfully.
78 Complete { message: String },
79 /// Initialization failed.
80 Failed { error_msg: String },
81 /// An existing configuration was found and loaded (skipping first-run).
82 ExistingLoaded { message: String },
83}
84
85/// Type alias for the callback function used during library initialization.
86/// The callback returns a simple Result to indicate success or failure, but
87/// doesn't need to return a boolean like PutCallback.
88pub type InitCallback =
89 Box<dyn FnMut(InitProgressEvent) -> BoxFuture<'static, Result<(), Error>> + Send + Sync>;
90
91#[inline]
92pub(crate) async fn invoke_init_callback(
93 callback: &mut Option<InitCallback>,
94 event: InitProgressEvent,
95) -> Result<(), Error> {
96 if let Some(cb) = callback {
97 let fut = cb(event);
98 fut.await
99 } else {
100 Ok(())
101 }
102}
103
104/// Events emitted during the `MutAnt::fetch` process.
105#[derive(Debug, Clone)]
106pub enum GetEvent {
107 /// Indicates the start of the download process, providing the total size.
108 StartingDownload { total_bytes: u64 },
109 /// Reports the progress of the download.
110 DownloadProgress { bytes_read: u64, total_bytes: u64 },
111 /// Indicates that the download has finished successfully.
112 DownloadFinished,
113}
114
115/// Callback type for Get/Fetch progress updates.
116/// The callback returns a simple Result to indicate success or failure.
117pub type GetCallback =
118 Box<dyn FnMut(GetEvent) -> BoxFuture<'static, Result<(), Error>> + Send + Sync>;
119
120// Helper function for invoking the Get callback if it exists.
121// Note: We might need a distinct invoke function if the return type differs significantly,
122// but since both InitCallback and GetCallback return Result<(), Error>, we might be able to reuse or generalize.
123// For now, let's assume invoke_init_callback logic works (simple propagation).
124#[inline]
125pub(crate) async fn invoke_get_callback(
126 callback: &mut Option<GetCallback>,
127 event: GetEvent,
128) -> Result<(), Error> {
129 if let Some(cb) = callback {
130 let fut = cb(event);
131 fut.await
132 } else {
133 Ok(())
134 }
135}