staticfilemap 0.8.0

Procedural macro to embed files during compilation with optional compression
Documentation
# staticfilemap

[![Crates.io](https://img.shields.io/crates/v/staticfilemap)](https://crates.io/crates/staticfilemap)
[![Docs.rs](https://img.shields.io/docsrs/staticfilemap)](https://docs.rs/staticfilemap)
[![Tests & Checks](https://img.shields.io/github/actions/workflow/status/Systemcluster/staticfilemap/tests.yml?label=tests%20%26%20checks)](https://github.com/Systemcluster/staticfilemap/actions/workflows/tests.yml)

**Procedural macro to embed files during compilation with optional compression.**

Similar to `include_file!` or [`include_dir!`](https://crates.io/crates/include_dir), but accepts a list of files that can be specified through environment variables and supports compression with [LZ4](https://github.com/lz4/lz4) or [zstd](https://github.com/facebook/zstd).

## Usage

Derive from `StaticFileMap` to create a map.

```rust
#[derive(StaticFileMap)]
#[files("README.md;LICENSE")]
struct StaticMap;
```

Specify the files to be included and the names they should be accessed by with the `files` and `names` attributes.
These can either be strings containing values separated with `;`, or environment variables containing them when the `parse` attribute is set to `env`.
Relative paths are resolved relative to `CARGO_MANIFEST_DIR`. If the `names` attribute is not specified, the names are inferred from the filenames.

### Compression

The compression level is controlled by the `compression` attribute. With a compression level above `0` the included files are compresed with Zstd. Zstd supports a compression level up to `22`.
Alternatively, LZ4 can be used for compression by setting the `algorithm` attribute to `lz4`. LZ4 accepts a compression level up to `12`.

The cargo features `zstd` and `lz4` are available to select compression support. `zstd` is enabled by default.

### Runtime

Files can be accessed as `&'static [u8]` slices by the `get(name)` and `get_match(name)` functions at runtime.
`get_match(name)` returns the file with a matching substring in its name if it exists and is unique.
`iter()`, `data()` and `keys()` are available to iterate over the included files.

See the examples, [the tests](tests/tests.rs) or [the implementation](src/lib.rs) for details.

### Dependency

```toml
[dependencies]
staticfilemap = "^0.8"
```

### Examples

```rust
use staticfilemap::StaticFileMap;

#[derive(StaticFileMap)]
#[names("a;b")]
#[files("README.md;LICENSE")]
struct StaticMap;

fn main() {
    let content: &[u8] = StaticMap::get("b").unwrap();
    let keys: &[&str] = StaticMap::keys();
}
```

```rust
use staticfilemap::StaticFileMap;
use zstd::decode_all;

#[derive(StaticFileMap)]
#[parse("env")]
#[names("FILENAMES")]
#[files("FILEPATHS")]
#[compression(8)]
struct StaticMap;

fn main() {
    let mut compressed = StaticMap::get("diogenes.txt")
        .expect("file diogenes.txt was not included");
    let content = decode_all(&mut compressed);
}
```

```rust
use staticfilemap::StaticFileMap;

#[derive(StaticFileMap)]
#[files("README.md;LICENSE")]
struct StaticMap;

fn main() {
    for (key, data) in StaticMap::iter() {
        println!("{}: {}", key, String::from_utf8_lossy(data));
    }
}
```

```rust
use staticfilemap::StaticFileMap;
use minilz4::Decode;
use std::io::Read;

#[derive(StaticFileMap)]
#[parse("env")]
#[names("FILENAMES")]
#[files("FILEPATHS")]
#[compression(8)]
#[algorithm("lz4")]
struct StaticMap;

fn main() {
    let compressed = StaticMap::get_match("diogenes")
        .expect("file matching diogenes was not included");
    let content = compressed.decode();
}
```