include_bytes_zstd_macro/
lib.rs1extern crate proc_macro;
4
5use std::io::Write;
6use std::path::PathBuf;
7
8use proc_macro::TokenStream;
9use proc_macro_crate::FoundCrate;
10use syn::{parse::Parse, parse_macro_input, LitInt, LitStr, Token};
11
12struct Arguments {
13 filename: LitStr,
14 _comma: Token![,],
15 level: LitInt,
16}
17
18impl Parse for Arguments {
19 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
20 Ok(Self {
21 filename: input.parse()?,
22 _comma: input.parse()?,
23 level: input.parse()?,
24 })
25 }
26}
27
28#[doc(hidden)]
29#[proc_macro]
30pub fn include_bytes_zstd(input: TokenStream) -> TokenStream {
31 let args = parse_macro_input!(input as Arguments);
33 let filename = PathBuf::from(args.filename.value());
34 let level = args.level.base10_parse::<i32>().unwrap();
35
36 let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
38 let filename = if filename.is_relative() {
39 manifest_dir.join(filename)
40 } else {
41 filename
42 };
43
44 let bytes = std::fs::read(filename).unwrap();
46 let mut compressed = vec![];
47 let mut encoder = zstd::Encoder::new(&mut compressed, level).unwrap();
48 encoder.write_all(&bytes).unwrap();
49 encoder.finish().unwrap();
50
51 let crate_name = proc_macro_crate::crate_name("include-bytes-zstd").unwrap();
53 let crate_name = match crate_name {
54 FoundCrate::Itself => "include_bytes_zstd".to_string(),
55 FoundCrate::Name(crate_name) => crate_name,
56 };
57 format!("{{ {crate_name}::decode(&{:?}) }}", compressed.as_slice())
58 .parse()
59 .unwrap()
60}