esp_config/
lib.rs

1#![doc = include_str!("../README.md")]
2//! ## Feature Flags
3#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
4#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
5#![cfg_attr(not(feature = "build"), no_std)]
6#![deny(missing_docs, rust_2018_idioms, rustdoc::all)]
7
8#[cfg(feature = "build")]
9mod generate;
10#[cfg(feature = "build")]
11pub use generate::{
12    ConfigOption,
13    DisplayHint,
14    Error,
15    Stability,
16    generate_config,
17    validator::Validator,
18    value::Value,
19};
20
21/// Parse the value of an environment variable as a [bool] at compile time.
22#[macro_export]
23macro_rules! esp_config_bool {
24    ( $var:expr ) => {
25        match env!($var).as_bytes() {
26            b"true" => true,
27            b"false" => false,
28            _ => ::core::panic!("boolean value must be either 'true' or 'false'"),
29        }
30    };
31}
32
33/// Parse the value of an environment variable as an integer at compile time.
34#[macro_export]
35macro_rules! esp_config_int {
36    ( $ty:ty, $var:expr ) => {
37        const { $crate::esp_config_int_parse!($ty, env!($var)) }
38    };
39}
40
41/// Get the string value of an environment variable at compile time.
42#[macro_export]
43macro_rules! esp_config_str {
44    ( $var:expr ) => {
45        env!($var)
46    };
47}
48
49/// Parse a string like "777" into an integer, which _can_ be used in a `const`
50/// context
51///
52/// Not inlined into `esp_config_int` to make this easy to test.
53#[doc(hidden)] // To avoid confusion with `esp_config_int`, hide this in the docs
54#[macro_export]
55macro_rules! esp_config_int_parse {
56    ( $ty:ty, $s:expr ) => {{
57        let val: $ty = match <$ty>::from_str_radix($s, 10) {
58            Ok(val) => val as $ty,
59            Err(_) => {
60                core::assert!(false, "Unable to parse a config value as a number.");
61                0
62            }
63        };
64        val
65    }};
66}
67
68#[cfg(test)]
69mod test {
70    // We can only test success in the const context
71    const _: () = {
72        core::assert!(esp_config_int_parse!(i64, "-77777") == -77777);
73        core::assert!(esp_config_int_parse!(isize, "-7777") == -7777);
74        core::assert!(esp_config_int_parse!(i32, "-999") == -999);
75        core::assert!(esp_config_int_parse!(i16, "-99") == -99);
76        core::assert!(esp_config_int_parse!(i8, "-9") == -9);
77
78        core::assert!(esp_config_int_parse!(u64, "77777") == 77777);
79        core::assert!(esp_config_int_parse!(usize, "7777") == 7777);
80        core::assert!(esp_config_int_parse!(u32, "999") == 999);
81        core::assert!(esp_config_int_parse!(u16, "99") == 99);
82        core::assert!(esp_config_int_parse!(u8, "9") == 9);
83    };
84
85    #[test]
86    #[should_panic]
87    fn test_expect_positive() {
88        esp_config_int_parse!(u8, "-5");
89    }
90
91    #[test]
92    #[should_panic]
93    fn test_invalid_digit() {
94        esp_config_int_parse!(u32, "a");
95    }
96}