Skip to main content

vite_static_derive/
lib.rs

1#![warn(clippy::pedantic)]
2#![allow(clippy::ref_option)]
3#![allow(clippy::match_wildcard_for_single_variants)]
4
5use proc_macro2::TokenStream;
6use quote::quote;
7use syn::{DeriveInput, parse_macro_input};
8
9mod dynamic;
10mod embedding;
11mod parse;
12
13use parse::parse_manifest_input;
14
15fn internal_manifest_derive(input: DeriveInput) -> syn::Result<TokenStream> {
16    let settings = parse_manifest_input(&input)?;
17    let ident = input.ident;
18
19    let trait_impl = if settings.no_embedding {
20        dynamic::generate(&ident, &settings)
21    } else {
22        embedding::generate(&ident, &settings)?
23    };
24
25    Ok(quote! {
26        #trait_impl
27
28        impl ::vite_static::Boxed<'static> for #ident {
29            fn boxed(&self) -> Box<dyn ::vite_static::Manifest<'static>> {
30                Box::new(#ident)
31            }
32        }
33    })
34}
35
36/// Derive macro, that generates `Manifest` trait implementation from Vite project and
37/// `.vite/manifest.json`.
38///
39/// See examples.
40///
41/// ```rust
42/// #[derive(Manifest)]
43/// #[vite_dist = "path/to/vite-project/dist"]
44/// #[cfg_attr(debug_assertions, no_embedding)]
45/// struct MyViteStatic;
46/// ```
47///
48/// # Options
49///
50/// > In all string options, you can use `env:YOUR_ENV_VAR` syntax to reference environment variable.
51///
52/// - `#[vite_dist = "..."]` _(required)_
53///
54///   Specify path to built Vite project files (aka `dist/` folder).
55///
56///   This folder must contain `.vite/manifest.json` file. (enabled by `build.manifest` vite config)
57///
58///   The value can be:
59///
60///     - Relative path (to `Cargo.toml`): `examples/vite-project/dist`
61///     - Absolute path: `/home/user/Projects/vite-project/dist`
62///     - Environment variable with relative/absolute path: `env:YOUR_ENV_VAR`
63///
64/// - `#[no_embedding]`
65///
66///   Make macro to NOT embed manifest or chunks.
67///
68///   With this option, macro doesn't parse or read manifest (or chunks). Manifest and chunks are read on runtime.
69///
70///   Recommended usage: enable `no_embedding` in debug builds to speed up build times.
71///
72///   ```
73///   #[cfg_attr(debug_assertions, no_embedding)]
74///   ```
75#[proc_macro_derive(Manifest, attributes(vite_dist, no_embedding))]
76pub fn manifest_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
77    let input = parse_macro_input!(input as DeriveInput);
78
79    match internal_manifest_derive(input) {
80        Ok(stream) => stream.into(),
81        Err(err) => proc_macro::TokenStream::from(err.to_compile_error()),
82    }
83}