stak_minifier_macro/
lib.rs

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
//! Macros to minify Scheme source codes.

extern crate alloc;

use alloc::str;
use core::error::Error;
use proc_macro::TokenStream;
use proc_macro2::Literal;
use quote::quote;
use stak_macro_util::{convert_result, read_source_file};
use syn::{parse_macro_input, LitStr};

/// Minifies source codes in Scheme.
///
/// # Examples
///
/// ```rust
/// const SCRIPT: &str = stak_minifier_macro::minify!("( foo  bar )\n\n(baz)");
///
/// assert_eq!(SCRIPT, "(foo bar)\n(baz)\n");
/// ```
#[proc_macro]
pub fn minify(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as LitStr);

    convert_result(minify_source(&input.value())).into()
}

/// Includes and minifies source codes in Scheme in a file.
///
/// # Examples
///
/// ```rust
/// const SCRIPT: &str = stak_minifier_macro::include_minified!("foo.scm");
///
/// assert_eq!(SCRIPT, "(foo bar)\n(baz)\n");
/// ```
#[proc_macro]
pub fn include_minified(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as LitStr);

    convert_result((|| minify_source(&read_source_file(input)?))()).into()
}

fn minify_source(source: &str) -> Result<proc_macro2::TokenStream, Box<dyn Error>> {
    let mut buffer = vec![];

    stak_minifier::minify(source.as_bytes(), &mut buffer)?;

    let target = Literal::string(str::from_utf8(&buffer)?);

    Ok(quote! { #target })
}