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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*!
# 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`, `usize`, `u8`, `u16`, `u32`, `u64`, `u128`, `isize`, `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,ignore
#[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,ignore
#[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,ignore
#[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]);
```

## No Std

This crate can work without std, but the `lazy_static_include_array` macro will be disabled unless using the **release** profile.

Enable the feature **no_std** to compile this crate without std.

```toml
[dependencies.lazy-static-include]
version = "*"
features = ["no_std"]
default-features = false
```

## 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
```
*/

#![cfg_attr(feature = "no_std", no_std)]

#[cfg(all(debug_assertions, not(feature = "no_std")))]
#[doc(hidden)]
pub extern crate syn;

#[cfg(all(debug_assertions, not(feature = "no_std")))]
#[doc(hidden)]
pub extern crate starts_ends_with_caseless;

mod macro_include_counter;
mod macro_include_str;
mod macro_include_bytes;
mod macro_include_array;