1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//! Types used to report and handle compilation progress.
use crate::lib::std::{borrow::Cow, fmt, string::String, sync::Arc};
use thiserror::Error;
/// Indicates the current compilation progress.
///
/// All fields are kept private for forwards compatibility and future extension.
/// Use the provided methods to access progress data.
#[derive(Clone, Debug, Default)]
pub struct CompilationProgress {
phase_name: Option<Cow<'static, str>>,
phase_step_count: Option<u64>,
phase_step: Option<u64>,
}
impl CompilationProgress {
/// Creates a new [`CompilationProgress`].
pub fn new(
phase_name: Option<Cow<'static, str>>,
phase_step_count: Option<u64>,
phase_step: Option<u64>,
) -> Self {
Self {
phase_name,
phase_step_count,
phase_step,
}
}
/// Returns the name of the phase currently being executed.
pub fn phase_name(&self) -> Option<&str> {
self.phase_name.as_deref()
}
/// Returns the total number of steps in the current phase, if known.
pub fn phase_step_count(&self) -> Option<u64> {
self.phase_step_count
}
/// Returns the index of the current step within the phase, if known.
pub fn phase_step(&self) -> Option<u64> {
self.phase_step
}
}
/// Error returned when the user requests to abort an expensive computation.
#[derive(Clone, Debug, Error)]
#[error("{reason}")]
pub struct UserAbort {
reason: String,
}
impl UserAbort {
/// Creates a new [`UserAbort`].
pub fn new(reason: impl Into<String>) -> Self {
Self {
reason: reason.into(),
}
}
/// Returns the configured reason.
pub fn reason(&self) -> &str {
&self.reason
}
}
/// Wraps a boxed callback that can receive compilation progress notifications.
#[derive(Clone)]
pub struct CompilationProgressCallback {
callback: Arc<dyn Fn(CompilationProgress) -> Result<(), UserAbort> + Send + Sync + 'static>,
}
impl CompilationProgressCallback {
/// Create a new callback wrapper.
///
/// The provided callback will be invoked with progress updates during the compilation process,
/// and has to return a `Result<(), UserAbort>`.
///
/// If the callback returns an error, the compilation will be aborted with a `CompileError::Aborted`.
pub fn new<F>(callback: F) -> Self
where
F: Fn(CompilationProgress) -> Result<(), UserAbort> + Send + Sync + 'static,
{
Self {
callback: Arc::new(callback),
}
}
/// Notify the callback about new progress information.
pub fn notify(&self, progress: CompilationProgress) -> Result<(), UserAbort> {
(self.callback)(progress)
}
}
impl fmt::Debug for CompilationProgressCallback {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("CompilationProgressCallback").finish()
}
}