Coverage Report

Created: 2025-02-21 07:11

/rust/registry/src/index.crates.io-6f17d22bba15001f/sysinfo-0.33.1/src/macros.rs
Line
Count
Source (jump to first uncovered line)
1
// Take a look at the license at the top of the repository in the LICENSE file.
2
3
#[cfg(feature = "debug")]
4
#[doc(hidden)]
5
#[allow(unused)]
6
macro_rules! sysinfo_debug {
7
    ($($x:tt)*) => {{
8
        eprintln!($($x)*);
9
    }}
10
}
11
12
#[cfg(not(feature = "debug"))]
13
#[doc(hidden)]
14
#[allow(unused)]
15
macro_rules! sysinfo_debug {
16
    ($($x:tt)*) => {{}};
17
}
18
19
#[cfg(feature = "system")]
20
macro_rules! declare_signals {
21
    ($kind:ty, _ => None,) => (
22
        use crate::Signal;
23
24
        pub(crate) const fn supported_signals() -> &'static [Signal] {
25
            &[]
26
        }
27
    );
28
29
    ($kind:ty, $(Signal::$signal:ident => $map:expr,)+ _ => None,) => (
30
        use crate::Signal;
31
32
        pub(crate) const fn supported_signals() -> &'static [Signal] {
33
            &[$(Signal::$signal,)*]
34
        }
35
36
        #[inline]
37
        pub(crate) fn convert_signal(s: Signal) -> Option<$kind> {
38
            match s {
39
                $(Signal::$signal => Some($map),)*
40
                _ => None,
41
            }
42
        }
43
    );
44
45
    ($kind:ty, $(Signal::$signal:ident => $map:expr,)+) => (
46
        use crate::Signal;
47
48
0
        pub(crate) const fn supported_signals() -> &'static [Signal] {
49
0
            &[$(Signal::$signal,)*]
50
0
        }
51
52
        #[inline]
53
0
        pub(crate) fn convert_signal(s: Signal) -> Option<$kind> {
54
0
            match s {
55
0
                $(Signal::$signal => Some($map),)*
56
            }
57
0
        }
58
    )
59
}
60
61
#[cfg(all(unix, not(feature = "unknown-ci")))]
62
#[allow(unused_macros)]
63
macro_rules! retry_eintr {
64
    (set_to_0 => $($t:tt)+) => {{
65
        let errno = crate::unix::libc_errno();
66
        if !errno.is_null() {
67
            *errno = 0;
68
        }
69
        retry_eintr!($($t)+)
70
    }};
71
    ($errno_value:ident => $($t:tt)+) => {{
72
        loop {
73
            let ret = $($t)+;
74
            if ret < 0 {
75
                let tmp = std::io::Error::last_os_error();
76
                if tmp.kind() == std::io::ErrorKind::Interrupted {
77
                    continue;
78
                }
79
                $errno_value = tmp.raw_os_error().unwrap_or(0);
80
            }
81
            break ret;
82
        }
83
    }};
84
    ($($t:tt)+) => {{
85
        loop {
86
            let ret = $($t)+;
87
            if ret < 0 && std::io::Error::last_os_error().kind() == std::io::ErrorKind::Interrupted {
88
                continue;
89
            }
90
            break ret;
91
        }
92
    }};
93
}
94
95
//FIXME: Remove this code if https://github.com/rust-lang/cfg-if/pull/78 is ever merged.
96
macro_rules! cfg_if {
97
    // match if/else chains with a final `else`
98
    (
99
        $(
100
            if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
101
        ) else+
102
        else { $( $e_tokens:tt )* }
103
    ) => {
104
        cfg_if! {
105
            @__items () ;
106
            $(
107
                (( $i_meta ) ( $( $i_tokens )* )) ,
108
            )+
109
            (() ( $( $e_tokens )* )) ,
110
        }
111
    };
112
113
    // Allow to multiple conditions in a same call.
114
    (
115
        $(
116
            if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
117
        ) else+
118
        else { $( $e_tokens:tt )* }
119
        if $($extra_conditions:tt)+
120
    ) => {
121
        cfg_if! {
122
            @__items () ;
123
            $(
124
                (( $i_meta ) ( $( $i_tokens )* )) ,
125
            )+
126
            (() ( $( $e_tokens )* )) ,
127
        }
128
        cfg_if! {
129
            if $($extra_conditions)+
130
        }
131
    };
132
133
    // match if/else chains lacking a final `else`
134
    (
135
        if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
136
        $(
137
            else if #[cfg( $e_meta:meta )] { $( $e_tokens:tt )* }
138
        )*
139
    ) => {
140
        cfg_if! {
141
            @__items () ;
142
            (( $i_meta ) ( $( $i_tokens )* )) ,
143
            $(
144
                (( $e_meta ) ( $( $e_tokens )* )) ,
145
            )*
146
        }
147
    };
148
149
    // Allow to multiple conditions in a same call.
150
    (
151
        if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
152
        $(
153
            else if #[cfg( $e_meta:meta )] { $( $e_tokens:tt )* }
154
        )*
155
        if $($extra_conditions:tt)+
156
    ) => {
157
        cfg_if! {
158
            @__items () ;
159
            (( $i_meta ) ( $( $i_tokens )* )) ,
160
            $(
161
                (( $e_meta ) ( $( $e_tokens )* )) ,
162
            )*
163
        }
164
        cfg_if! {
165
            if $($extra_conditions)+
166
        }
167
    };
168
169
    // Internal and recursive macro to emit all the items
170
    //
171
    // Collects all the previous cfgs in a list at the beginning, so they can be
172
    // negated. After the semicolon is all the remaining items.
173
    (@__items ( $( $_:meta , )* ) ; ) => {};
174
    (
175
        @__items ( $( $no:meta , )* ) ;
176
        (( $( $yes:meta )? ) ( $( $tokens:tt )* )) ,
177
        $( $rest:tt , )*
178
    ) => {
179
        // Emit all items within one block, applying an appropriate #[cfg]. The
180
        // #[cfg] will require all `$yes` matchers specified and must also negate
181
        // all previous matchers.
182
        #[cfg(all(
183
            $( $yes , )?
184
            not(any( $( $no ),* ))
185
        ))]
186
        cfg_if! { @__identity $( $tokens )* }
187
188
        // Recurse to emit all other items in `$rest`, and when we do so add all
189
        // our `$yes` matchers to the list of `$no` matchers as future emissions
190
        // will have to negate everything we just matched as well.
191
        cfg_if! {
192
            @__items ( $( $no , )* $( $yes , )? ) ;
193
            $( $rest , )*
194
        }
195
    };
196
197
    // Internal macro to make __apply work out right for different match types,
198
    // because of how macros match/expand stuff.
199
    (@__identity $( $tokens:tt )* ) => {
200
        $( $tokens )*
201
    };
202
}
203
204
#[cfg(test)]
205
#[allow(unexpected_cfgs)]
206
mod tests {
207
    cfg_if! {
208
        if #[cfg(test)] {
209
            use core::option::Option as Option2;
210
            fn works1() -> Option2<u32> { Some(1) }
211
        } else {
212
            fn works1() -> Option<u32> { None }
213
        }
214
    }
215
216
    cfg_if! {
217
        if #[cfg(foo)] {
218
            fn works2() -> bool { false }
219
        } else if #[cfg(test)] {
220
            fn works2() -> bool { true }
221
        } else {
222
            fn works2() -> bool { false }
223
        }
224
    }
225
226
    cfg_if! {
227
        if #[cfg(foo)] {
228
            fn works3() -> bool { false }
229
        } else {
230
            fn works3() -> bool { true }
231
        }
232
    }
233
234
    cfg_if! {
235
        if #[cfg(test)] {
236
            use core::option::Option as Option3;
237
            fn works4() -> Option3<u32> { Some(1) }
238
        }
239
    }
240
241
    cfg_if! {
242
        if #[cfg(foo)] {
243
            fn works5() -> bool { false }
244
        } else if #[cfg(test)] {
245
            fn works5() -> bool { true }
246
        }
247
    }
248
249
    cfg_if! {
250
        if #[cfg(foo)] {
251
            fn works6() -> bool { false }
252
        } else if #[cfg(test)] {
253
            fn works6() -> bool { true }
254
        }
255
        if #[cfg(test)] {
256
            fn works7() -> bool { true }
257
        } else {
258
            fn works7() -> bool { false }
259
        }
260
    }
261
262
    cfg_if! {
263
        if #[cfg(test)] {
264
            fn works8() -> bool { true }
265
        } else if #[cfg(foo)] {
266
            fn works8() -> bool { false }
267
        }
268
        if #[cfg(foo)] {
269
            fn works9() -> bool { false }
270
        } else if #[cfg(test)] {
271
            fn works9() -> bool { true }
272
        }
273
    }
274
275
    #[test]
276
    fn it_works() {
277
        assert!(works1().is_some());
278
        assert!(works2());
279
        assert!(works3());
280
        assert!(works4().is_some());
281
        assert!(works5());
282
        assert!(works6());
283
        assert!(works7());
284
        assert!(works8());
285
        assert!(works9());
286
    }
287
288
    #[test]
289
    #[allow(clippy::assertions_on_constants)]
290
    fn test_usage_within_a_function() {
291
        cfg_if! {if #[cfg(debug_assertions)] {
292
            // we want to put more than one thing here to make sure that they
293
            // all get configured properly.
294
            assert!(cfg!(debug_assertions));
295
            assert_eq!(4, 2+2);
296
        } else {
297
            assert!(works1().is_some());
298
            assert_eq!(10, 5+5);
299
        }}
300
    }
301
302
    #[allow(dead_code)]
303
    trait Trait {
304
        fn blah(&self);
305
    }
306
307
    #[allow(dead_code)]
308
    struct Struct;
309
310
    impl Trait for Struct {
311
        cfg_if! {
312
            if #[cfg(feature = "blah")] {
313
                fn blah(&self) {
314
                    unimplemented!();
315
                }
316
            } else {
317
                fn blah(&self) {
318
                    unimplemented!();
319
                }
320
            }
321
        }
322
    }
323
}