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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use super::Status;
use log::warn;
#[must_use]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Completion<T> {
status: Status,
result: T,
}
impl<T> Completion<T> {
pub fn new(status: Status, result: T) -> Self {
if status.is_error() {
built_with_error(status);
}
Self { status, result }
}
pub fn status(&self) -> Status {
self.status
}
pub fn split(self) -> (Status, T) {
(self.status, self.result)
}
pub fn log(self) -> T {
if self.status != Status::SUCCESS {
log_warning(self.status);
}
self.result
}
pub fn unwrap(self) -> T {
if self.status != Status::SUCCESS {
unwrap_failed(
"Called `Completion::unwrap()` with a warning status",
self.status,
);
}
self.result
}
pub fn expect(self, msg: &str) -> T {
if self.status != Status::SUCCESS {
unwrap_failed(msg, self.status);
}
self.result
}
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Completion<U> {
Completion {
status: self.status,
result: f(self.result),
}
}
pub fn with_status(self, extra_status: Status) -> Self {
if extra_status.is_success() {
self
} else {
Completion::new(extra_status, self.log())
}
}
}
impl From<Status> for Completion<()> {
fn from(status: Status) -> Self {
Completion::new(status, ())
}
}
impl<T> From<T> for Completion<T> {
fn from(result: T) -> Self {
Completion::new(Status::SUCCESS, result)
}
}
#[inline(never)]
#[cold]
fn built_with_error(error: Status) -> ! {
panic!(
"Completion was incorrectly built with error status: {:?}",
error
)
}
#[inline(never)]
#[cold]
fn unwrap_failed(msg: &str, warning: Status) -> ! {
panic!("{}: {:?}", msg, warning)
}
#[inline(never)]
#[cold]
fn log_warning(warning: Status) {
warn!("Encountered UEFI warning: {:?}", warning)
}