vite-static-derive 0.5.0

Derive macro support for `vite-static`
Documentation
#![warn(clippy::pedantic)]
#![allow(clippy::ref_option)]
#![allow(clippy::match_wildcard_for_single_variants)]

use proc_macro2::TokenStream;
use quote::quote;
use syn::{DeriveInput, parse_macro_input};

mod dynamic;
mod embedding;
mod parse;

use parse::parse_manifest_input;

fn internal_manifest_derive(input: DeriveInput) -> syn::Result<TokenStream> {
    let settings = parse_manifest_input(&input)?;
    let ident = input.ident;

    let trait_impl = if settings.no_embedding {
        dynamic::generate(&ident, &settings)
    } else {
        embedding::generate(&ident, &settings)?
    };

    Ok(quote! {
        #trait_impl

        impl ::vite_static::Boxed<'static> for #ident {
            fn boxed(&self) -> Box<dyn ::vite_static::Manifest<'static>> {
                Box::new(#ident)
            }
        }
    })
}

/// Derive macro, that generates `Manifest` trait implementation from Vite project and
/// `.vite/manifest.json`.
///
/// See examples.
///
/// ```rust
/// #[derive(Manifest)]
/// #[vite_dist = "path/to/vite-project/dist"]
/// #[cfg_attr(debug_assertions, no_embedding)]
/// struct MyViteStatic;
/// ```
///
/// # Options
///
/// > In all string options, you can use `env:YOUR_ENV_VAR` syntax to reference environment variable.
///
/// - `#[vite_dist = "..."]` _(required)_
///
///   Specify path to built Vite project files (aka `dist/` folder).
///
///   This folder must contain `.vite/manifest.json` file. (enabled by `build.manifest` vite config)
///
///   The value can be:
///
///     - Relative path (to `Cargo.toml`): `examples/vite-project/dist`
///     - Absolute path: `/home/user/Projects/vite-project/dist`
///     - Environment variable with relative/absolute path: `env:YOUR_ENV_VAR`
///
/// - `#[no_embedding]`
///
///   Make macro to NOT embed manifest or chunks.
///
///   With this option, macro doesn't parse or read manifest (or chunks). Manifest and chunks are read on runtime.
///
///   Recommended usage: enable `no_embedding` in debug builds to speed up build times.
///
///   ```
///   #[cfg_attr(debug_assertions, no_embedding)]
///   ```
#[proc_macro_derive(Manifest, attributes(vite_dist, no_embedding))]
pub fn manifest_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let input = parse_macro_input!(input as DeriveInput);

    match internal_manifest_derive(input) {
        Ok(stream) => stream.into(),
        Err(err) => proc_macro::TokenStream::from(err.to_compile_error()),
    }
}