1
- use core:: result;
2
- use log:: warn;
3
-
4
1
/// Definition of UEFI's standard status codes
5
2
mod status;
6
3
pub use self :: status:: Status ;
7
4
8
- /// This type is used when an UEFI operation has completed, but some non-fatal
9
- /// problems may have been encountered along the way
10
- #[ must_use]
11
- #[ derive( Clone , Copy , Debug , PartialEq ) ]
12
- pub enum Completion < T > {
13
- /// The operation completed without problems
14
- Success ( T ) ,
5
+ /// Completions are used to model operations which have completed, but may have
6
+ /// encountered non-fatal errors ("warnings") along the way
7
+ mod completion;
8
+ pub use self :: completion:: Completion ;
15
9
16
- /// The operation completed, but some non-fatal issues were encountered
17
- Warning ( T , Status ) ,
18
- }
10
+ /// Return type of many UEFI functions.
11
+ pub type Result < T > = core:: result:: Result < Completion < T > , Status > ;
19
12
20
- impl < T > Completion < T > {
21
- /// Split the completion into a (status, value) pair
22
- pub fn split ( self ) -> ( T , Status ) {
23
- match self {
24
- Completion :: Success ( res) => ( res, Status :: SUCCESS ) ,
25
- Completion :: Warning ( res, stat) => ( res, stat) ,
26
- }
27
- }
13
+ /// Extension trait for Result which helps dealing with UEFI's warnings
14
+ pub trait ResultExt < T > {
15
+ /// Treat warnings as errors
16
+ fn warn_error ( self ) -> core:: result:: Result < T , Status > ;
28
17
29
- /// Access the inner value, logging the warning if there is any
30
- pub fn value ( self ) -> T {
31
- match self {
32
- Completion :: Success ( res) => res,
33
- Completion :: Warning ( res, stat) => {
34
- warn ! ( "Encountered UEFI warning: {:?}" , stat) ;
35
- res
36
- }
37
- }
38
- }
18
+ /// Ignore warnings, keepint a trace of them in the logs
19
+ fn warn_log ( self ) -> core:: result:: Result < T , Status > ;
39
20
40
- /// Assume that no warning occured, panic if not
41
- pub fn unwrap ( self ) -> T {
42
- match self {
43
- Completion :: Success ( res) => res,
44
- Completion :: Warning ( _, w) => {
45
- unwrap_failed ( "Called `Completion::unwrap()` on a `Warning` value" , w)
46
- }
47
- }
48
- }
21
+ /// Expect success without warnings, panic otherwise
22
+ fn warn_unwrap ( self ) -> T ;
49
23
50
- /// Assume that no warning occured, panic with provided message if not
51
- pub fn expect ( self , msg : & str ) -> T {
52
- match self {
53
- Completion :: Success ( res) => res,
54
- Completion :: Warning ( _, w) => unwrap_failed ( msg, w) ,
55
- }
56
- }
24
+ /// Expect success without warnings, panic with provided message otherwise
25
+ fn warn_expect ( self , msg : & str ) -> T ;
26
+ }
57
27
58
- /// Transform the inner value without unwrapping the Completion
59
- pub fn map < U > ( self , f : impl Fn ( T ) -> U ) -> Completion < U > {
28
+ impl < T > ResultExt < T > for Result < T > {
29
+ fn warn_error ( self ) -> core :: result :: Result < T , Status > {
60
30
match self {
61
- Completion :: Success ( res) => Completion :: Success ( f ( res) ) ,
62
- Completion :: Warning ( res, stat) => Completion :: Warning ( f ( res) , stat) ,
31
+ Ok ( Completion :: Success ( v) ) => Ok ( v) ,
32
+ Ok ( Completion :: Warning ( _, s) ) => Err ( s) ,
33
+ Err ( s) => Err ( s) ,
63
34
}
64
35
}
65
36
66
- /// Merge this completion with a success or warning status
67
- ///
68
- /// Since this type only has storage for one warning, if two warnings must
69
- /// be stored, one of them will be spilled into the logs.
70
- ///
71
- pub fn with_warning ( self , extra_stat : Status ) -> Self {
72
- match self {
73
- Completion :: Success ( res) => {
74
- if extra_stat. is_success ( ) {
75
- Completion :: Success ( res)
76
- } else {
77
- Completion :: Warning ( res, extra_stat)
78
- }
79
- }
80
- Completion :: Warning ( res, stat) => {
81
- if extra_stat. is_success ( ) {
82
- Completion :: Warning ( res, stat)
83
- } else {
84
- warn ! ( "Encountered UEFI warning {:?}" , stat) ;
85
- Completion :: Warning ( res, extra_stat)
86
- }
87
- }
88
- }
37
+ fn warn_log ( self ) -> core:: result:: Result < T , Status > {
38
+ self . map ( |completion| completion. value ( ) )
89
39
}
90
- }
91
40
92
- impl < T > From < T > for Completion < T > {
93
- fn from ( res : T ) -> Self {
94
- Completion :: Success ( res)
41
+ fn warn_unwrap ( self ) -> T {
42
+ self . unwrap ( ) . unwrap ( )
95
43
}
96
- }
97
-
98
- // This is a separate function to reduce the code size of the methods
99
- #[ inline( never) ]
100
- #[ cold]
101
- fn unwrap_failed ( msg : & str , warning : Status ) -> ! {
102
- panic ! ( "{}: {:?}" , msg, warning)
103
- }
104
44
105
- /// Return type of many UEFI functions.
106
- pub type Result < T > = result:: Result < Completion < T > , Status > ;
45
+ fn warn_expect ( self , msg : & str ) -> T {
46
+ self . expect ( msg) . expect ( msg)
47
+ }
48
+ }
0 commit comments