~repos /rust-embed

#rust#proc-macro#http

git clone https://pyrossh.dev/repos/rust-embed.git

rust macro which loads files into the rust binary at compile time during release and loads the file from the fs during dev.


1fb92450 Peter John

2 years ago
Merge pull request #212 from osiewicz/issue-182/include_flate_0.2
Files changed (1) hide show
  1. impl/src/lib.rs +40 -18
impl/src/lib.rs CHANGED
@@ -6,10 +6,16 @@ extern crate proc_macro;
6
6
 
7
7
  use proc_macro::TokenStream;
8
8
  use proc_macro2::TokenStream as TokenStream2;
9
+ use std::{
10
+ env,
11
+ iter::FromIterator,
9
- use std::{env, path::Path};
12
+ path::{Path, PathBuf},
13
+ };
10
14
  use syn::{Data, DeriveInput, Expr, ExprLit, Fields, Lit, Meta, MetaNameValue};
11
15
 
16
+ fn embedded(
12
- fn embedded(ident: &syn::Ident, folder_path: String, prefix: Option<&str>, includes: &[String], excludes: &[String]) -> TokenStream2 {
17
+ ident: &syn::Ident, relative_folder_path: Option<&str>, absolute_folder_path: String, prefix: Option<&str>, includes: &[String], excludes: &[String],
18
+ ) -> TokenStream2 {
13
19
  extern crate rust_embed_utils;
14
20
 
15
21
  let mut match_values = Vec::<TokenStream2>::new();
@@ -17,8 +23,8 @@ fn embedded(ident: &syn::Ident, folder_path: String, prefix: Option<&str>, inclu
17
23
 
18
24
  let includes: Vec<&str> = includes.iter().map(AsRef::as_ref).collect();
19
25
  let excludes: Vec<&str> = excludes.iter().map(AsRef::as_ref).collect();
20
- for rust_embed_utils::FileEntry { rel_path, full_canonical_path } in rust_embed_utils::get_files(folder_path, &includes, &excludes) {
26
+ for rust_embed_utils::FileEntry { rel_path, full_canonical_path } in rust_embed_utils::get_files(absolute_folder_path.clone(), &includes, &excludes) {
21
- match_values.push(embed_file(&rel_path, &full_canonical_path));
27
+ match_values.push(embed_file(relative_folder_path.clone(), &rel_path, &full_canonical_path));
22
28
 
23
29
  list_values.push(if let Some(prefix) = prefix {
24
30
  format!("{}{}", prefix, rel_path)
@@ -153,13 +159,22 @@ fn dynamic(ident: &syn::Ident, folder_path: String, prefix: Option<&str>, includ
153
159
  }
154
160
  }
155
161
 
162
+ fn generate_assets(
156
- fn generate_assets(ident: &syn::Ident, folder_path: String, prefix: Option<String>, includes: Vec<String>, excludes: Vec<String>) -> TokenStream2 {
163
+ ident: &syn::Ident, relative_folder_path: Option<&str>, absolute_folder_path: String, prefix: Option<String>, includes: Vec<String>, excludes: Vec<String>,
164
+ ) -> TokenStream2 {
157
- let embedded_impl = embedded(ident, folder_path.clone(), prefix.as_deref(), &includes, &excludes);
165
+ let embedded_impl = embedded(
166
+ ident,
167
+ relative_folder_path,
168
+ absolute_folder_path.clone(),
169
+ prefix.as_deref(),
170
+ &includes,
171
+ &excludes,
172
+ );
158
173
  if cfg!(feature = "debug-embed") {
159
174
  return embedded_impl;
160
175
  }
161
176
 
162
- let dynamic_impl = dynamic(ident, folder_path, prefix.as_deref(), &includes, &excludes);
177
+ let dynamic_impl = dynamic(ident, absolute_folder_path, prefix.as_deref(), &includes, &excludes);
163
178
 
164
179
  quote! {
165
180
  #embedded_impl
@@ -167,7 +182,7 @@ fn generate_assets(ident: &syn::Ident, folder_path: String, prefix: Option<Strin
167
182
  }
168
183
  }
169
184
 
170
- fn embed_file(rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
185
+ fn embed_file(folder_path: Option<&str>, rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
171
186
  let file = rust_embed_utils::read_file_from_fs(Path::new(full_canonical_path)).expect("File should be readable");
172
187
  let hash = file.metadata.sha256_hash();
173
188
  let last_modified = match file.metadata.last_modified() {
@@ -183,8 +198,11 @@ fn embed_file(rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
183
198
  let mimetype_tokens = TokenStream2::new();
184
199
 
185
200
  let embedding_code = if cfg!(feature = "compression") {
201
+ // Print some debugging information
202
+ let full_relative_path = PathBuf::from_iter([folder_path.expect("folder_path must be provided under `compression` feature"), rel_path]);
203
+ let full_relative_path = full_relative_path.to_string_lossy();
186
204
  quote! {
187
- rust_embed::flate!(static FILE: [u8] from #full_canonical_path);
205
+ rust_embed::flate!(static FILE: [u8] from #full_relative_path);
188
206
  let bytes = &FILE[..];
189
207
  }
190
208
  } else {
@@ -249,26 +267,30 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> TokenStream2 {
249
267
  let folder_path = shellexpand::full(&folder_path).unwrap().to_string();
250
268
 
251
269
  // Base relative paths on the Cargo.toml location
252
- let folder_path = if Path::new(&folder_path).is_relative() {
270
+ let (relative_path, absolute_folder_path) = if Path::new(&folder_path).is_relative() {
253
- Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap())
271
+ let absolute_path = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap())
254
- .join(folder_path)
272
+ .join(&folder_path)
255
273
  .to_str()
256
274
  .unwrap()
257
- .to_owned()
275
+ .to_owned();
276
+ (Some(folder_path.clone()), absolute_path)
258
277
  } else {
278
+ if cfg!(feature = "compression") {
279
+ panic!("`folder` must be a relative path under `compression` feature.")
280
+ }
259
- folder_path
281
+ (None, folder_path)
260
282
  };
261
283
 
262
- if !Path::new(&folder_path).exists() {
284
+ if !Path::new(&absolute_folder_path).exists() {
263
285
  let mut message = format!(
264
286
  "#[derive(RustEmbed)] folder '{}' does not exist. cwd: '{}'",
265
- folder_path,
287
+ absolute_folder_path,
266
288
  std::env::current_dir().unwrap().to_str().unwrap()
267
289
  );
268
290
 
269
291
  // Add a message about the interpolate-folder-path feature if the path may
270
292
  // include a variable
271
- if folder_path.contains('$') && cfg!(not(feature = "interpolate-folder-path")) {
293
+ if absolute_folder_path.contains('$') && cfg!(not(feature = "interpolate-folder-path")) {
272
294
  message += "\nA variable has been detected. RustEmbed can expand variables \
273
295
  when the `interpolate-folder-path` feature is enabled.";
274
296
  }
@@ -276,7 +298,7 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> TokenStream2 {
276
298
  panic!("{}", message);
277
299
  };
278
300
 
279
- generate_assets(&ast.ident, folder_path, prefix, includes, excludes)
301
+ generate_assets(&ast.ident, relative_path.as_deref(), absolute_folder_path, prefix, includes, excludes)
280
302
  }
281
303
 
282
304
  #[proc_macro_derive(RustEmbed, attributes(folder, prefix, include, exclude))]