1#![doc = include_str!("../README.md")]
2#![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::{generate_config, Error, Validator, Value};
12
13#[macro_export]
15macro_rules! esp_config_bool {
16 ( $var:expr ) => {
17 match env!($var).as_bytes() {
18 b"true" => true,
19 b"false" => false,
20 _ => ::core::panic!("boolean value must be either 'true' or 'false'"),
21 }
22 };
23}
24
25#[macro_export]
28macro_rules! esp_config_int {
29 ( $ty:ty, $var:expr ) => {
30 const {
31 const BYTES: &[u8] = env!($var).as_bytes();
32 $crate::esp_config_int_parse!($ty, BYTES)
33 }
34 };
35}
36
37#[macro_export]
39macro_rules! esp_config_str {
40 ( $var:expr ) => {
41 env!($var)
42 };
43}
44
45#[doc(hidden)] #[macro_export]
49macro_rules! esp_config_int_parse {
50 ( $ty:ty, $bytes:expr ) => {{
51 let mut bytes = $bytes;
52 let mut val: $ty = 0;
53 let mut sign_seen = false;
54 let mut is_negative = false;
55
56 while let [byte, rest @ ..] = bytes {
57 match *byte {
58 b'0'..=b'9' => {
59 val = val * 10 + (*byte - b'0') as $ty;
60 }
61 b'-' | b'+' if !sign_seen => {
62 is_negative = *byte == b'-';
63 sign_seen = true;
64 }
65 _ => ::core::panic!("invalid character encountered while parsing integer"),
66 }
67
68 bytes = rest;
69 }
70
71 if is_negative {
72 let original = val;
73 val -= original;
75 val -= original;
76 }
77
78 val
79 }};
80}
81
82#[cfg(test)]
83mod test {
84 const _: () = {
86 core::assert!(esp_config_int_parse!(i64, "-77777".as_bytes()) == -77777);
87 core::assert!(esp_config_int_parse!(isize, "-7777".as_bytes()) == -7777);
88 core::assert!(esp_config_int_parse!(i32, "-999".as_bytes()) == -999);
89 core::assert!(esp_config_int_parse!(i16, "-99".as_bytes()) == -99);
90 core::assert!(esp_config_int_parse!(i8, "-9".as_bytes()) == -9);
91
92 core::assert!(esp_config_int_parse!(u64, "77777".as_bytes()) == 77777);
93 core::assert!(esp_config_int_parse!(usize, "7777".as_bytes()) == 7777);
94 core::assert!(esp_config_int_parse!(u32, "999".as_bytes()) == 999);
95 core::assert!(esp_config_int_parse!(u16, "99".as_bytes()) == 99);
96 core::assert!(esp_config_int_parse!(u8, "9".as_bytes()) == 9);
97 };
98
99 #[test]
100 #[should_panic]
101 fn test_expect_positive() {
102 esp_config_int_parse!(u8, "-5".as_bytes());
103 }
104
105 #[test]
106 #[should_panic]
107 fn test_invalid_digit() {
108 esp_config_int_parse!(u32, "a".as_bytes());
109 }
110}