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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
/*! # Lazy Static Include This crate provides `lazy_static_include_bytes` and `lazy_static_include_str` macros to replace `include_bytes` and `include_str` macros. Why should we do that? Because the original `include_bytes` and `include_str` macros bring extra data from files into the compiled executable binary file, the time for compiling surges. High compilation time is detrimental to software development. `lazy_static_include_bytes` and `lazy_static_include_str` macros can help you **lazy load** data from files when you are not using the **release** profile. In other words, if you are using `include_bytes` and `include_str` macros, and you think your compilation time is too high to wait, you can choose to use `lazy_static_include_bytes` and `lazy_static_include_str` macros. `lazy_static_include_bytes` and `lazy_static_include_str` macros include data from files into the compiled executable binary file **only** when you are using the **release** profile. Be careful when you distribute your program. The paths used for `lazy_static_include_bytes` and `lazy_static_include_str` are relative to **CARGO_MANIFEST_DIR**. ## Examples ```rust #[macro_use] extern crate lazy_static_include; #[macro_use] extern crate lazy_static; lazy_static_include_str!(TEST, "data/test.txt"); lazy_static_include_str!(pub TEST2, "data/test-2.txt"); assert_eq!("This is just a test text.", TEST); assert_eq!(TEST2, "Some text..."); ``` ```rust #[macro_use] extern crate lazy_static_include; #[macro_use] extern crate lazy_static; lazy_static_include_bytes!(TEST, "data/test.txt", "data/test-2.txt"); assert_eq!("This is just a test text.".as_bytes(), TEST[0]); assert_eq!(TEST[1], "Some text...".as_bytes()); ``` You should notice that the struct created from `lazy_static_include_bytes` and `lazy_static_include_str` macros isn't equal to `&'static [u8]` or `&'static str`. If you want to get an exact `&'static [u8]` or `&'static str` reference, you need to **dereference the struct**. ```rust #[macro_use] extern crate lazy_static_include; #[macro_use] extern crate lazy_static; lazy_static_include_bytes!(TEST, "data/test.txt"); let data: &'static [u8] = *TEST; ``` If you include str and bytes from multiple files, after dereferencing the struct, you will get a `Vec<&'static [u8]>` or a `Vec<&'static str>`. In order to not move out of borrowed content, use **&*** to get the reference of that `Vec`. ```rust #[macro_use] extern crate lazy_static_include; #[macro_use] extern crate lazy_static; lazy_static_include_str!(TEST, "data/test.txt", "data/test-2.txt"); let v: &Vec<&'static str> = &*TEST; ``` ## Include Array There is a special macro `lazy_static_include_array` which can include arrays from files. The array is fixed sized and can be one of these following types: `bool`, `char`, `u8`, `u16`, `u32`, `u64`, `u128`, `i8`, `i16`, `i32`, `i64`, `i128`, `f32`, `f64`, `&'static str`. Also, the `lazy_static_include_array` macro includes data from files into the compiled executable binary file **only** when you are using the **release** profile. Be careful when you distribute your program. ```rust #[macro_use] extern crate lazy_static_include; #[macro_use] extern crate lazy_static; lazy_static_include_array!(TEST: [u64; 5], "data/u64_array.txt"); assert_eq!(123, TEST[0]); assert_eq!(456, TEST[1]); assert_eq!(789, TEST[2]); assert_eq!(1000, TEST[3]); assert_eq!(500000000000u64, TEST[4]); ``` ```rust #[macro_use] extern crate lazy_static_include; #[macro_use] extern crate lazy_static; lazy_static_include_array!(TEST: [i32; 5], "data/i32_array.txt", "data/i32_array-2.txt"); assert_eq!(123, TEST[0][0]); assert_eq!(-456, TEST[0][1]); assert_eq!(789, TEST[0][2]); assert_eq!(1000, TEST[0][3]); assert_eq!(5000, TEST[0][4]); assert_eq!(-1, TEST[1][0]); assert_eq!(-2, TEST[1][1]); assert_eq!(-3, TEST[1][2]); assert_eq!(-4, TEST[1][3]); assert_eq!(-5, TEST[1][4]); ``` ```rust #[macro_use] extern crate lazy_static_include; #[macro_use] extern crate lazy_static; lazy_static_include_array!(pub TEST: [&'static str; 3], "data/string_array.txt"); assert_eq!("Hi", TEST[0]); assert_eq!("Hello", TEST[1]); assert_eq!("哈囉", TEST[2]); ``` ## Benchmark Using static mechanisms makes your program faster. See my benchmark result below (Intel i7-6700HQ, ran on 2018/11/14): ```text include_str/include_str_no_static time: [8.3773 us 8.4061 us 8.4361 us] include_str/include_str_native_static time: [965.65 ns 969.47 ns 973.04 ns] include_str/include_str_lazy_static time: [955.93 ns 958.78 ns 961.88 ns] include_bytes/include_bytes_no_static time: [7.7806 us 7.8056 us 7.8318 us] include_bytes/include_bytes_native_static time: [418.43 ns 420.12 ns 421.83 ns] include_bytes/include_bytes_lazy_static time: [413.43 ns 415.14 ns 417.37 ns] include_array/include_array_no_static time: [30.125 us 30.285 us 30.445 us] include_array/include_array_native_static time: [38.510 ns 38.640 ns 38.786 ns] include_array/include_array_lazy_static time: [39.713 ns 39.863 ns 40.019 ns] ``` When using the **release** profile, the performance of `lazy_static_include_*` is very close to `include_*`. That means you don't need to worry about the overhead, but just enjoy the faster compilation time. You can run the benchmark program by executing, ```bash cargo bench ``` */ #![no_std] mod macro_include_counter; mod macro_include_str; mod macro_include_bytes; mod macro_include_array;