~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.


769f661b Peter John

9 months ago
Merge pull request #256 from lirannl/master
Files changed (3) hide show
  1. impl/src/lib.rs +12 -3
  2. readme.md +5 -0
  3. tests/allow_missing.rs +15 -0
impl/src/lib.rs CHANGED
@@ -10,6 +10,7 @@ use rust_embed_utils::PathMatcher;
10
10
  use std::{
11
11
  collections::BTreeMap,
12
12
  env,
13
+ io::ErrorKind,
13
14
  iter::FromIterator,
14
15
  path::{Path, PathBuf},
15
16
  };
@@ -135,7 +136,14 @@ fn dynamic(
135
136
  .map(|mut file| { file.data = ::std::default::Default::default(); file })
136
137
  });
137
138
 
139
+ let non_canonical_folder_path = Path::new(&folder_path);
140
+ let canonical_folder_path = non_canonical_folder_path
141
+ .canonicalize()
142
+ .or_else(|err| match err {
143
+ err if err.kind() == ErrorKind::NotFound => Ok(non_canonical_folder_path.to_owned()),
144
+ err => Err(err),
145
+ })
138
- let canonical_folder_path = Path::new(&folder_path).canonicalize().expect("folder path must resolve to an absolute path");
146
+ .expect("folder path must resolve to an absolute path");
139
147
  let canonical_folder_path = canonical_folder_path.to_str().expect("absolute folder path must be valid unicode");
140
148
 
141
149
  quote! {
@@ -339,6 +347,7 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> syn::Result<TokenStream2> {
339
347
  let includes = find_attribute_values(ast, "include");
340
348
  let excludes = find_attribute_values(ast, "exclude");
341
349
  let metadata_only = find_bool_attribute(ast, "metadata_only").unwrap_or(false);
350
+ let allow_missing = find_bool_attribute(ast, "allow_missing").unwrap_or(false);
342
351
 
343
352
  #[cfg(not(feature = "include-exclude"))]
344
353
  if !includes.is_empty() || !excludes.is_empty() {
@@ -368,7 +377,7 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> syn::Result<TokenStream2> {
368
377
  (None, folder_path)
369
378
  };
370
379
 
371
- if !Path::new(&absolute_folder_path).exists() {
380
+ if !Path::new(&absolute_folder_path).exists() && !allow_missing {
372
381
  let mut message = format!(
373
382
  "#[derive(RustEmbed)] folder '{}' does not exist. cwd: '{}'",
374
383
  absolute_folder_path,
@@ -397,7 +406,7 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> syn::Result<TokenStream2> {
397
406
  )
398
407
  }
399
408
 
400
- #[proc_macro_derive(RustEmbed, attributes(folder, prefix, include, exclude, metadata_only, crate_path))]
409
+ #[proc_macro_derive(RustEmbed, attributes(folder, prefix, include, exclude, allow_missing, metadata_only, crate_path))]
401
410
  pub fn derive_input_object(input: TokenStream) -> TokenStream {
402
411
  let ast = parse_macro_input!(input as DeriveInput);
403
412
  match impl_rust_embed(&ast) {
readme.md CHANGED
@@ -93,6 +93,11 @@ be included in the file paths returned by `iter`.
93
93
  You can add `#[metadata_only = true]` to the `RustEmbed` struct to exclude file contents from the
94
94
  binary. Only file paths and metadata will be embedded.
95
95
 
96
+ ### `allow_missing`
97
+
98
+ You can add `#[allow_missing = true]` to the `RustEmbed` struct to allow the embedded folder to be missing.
99
+ In that case, RustEmbed will be empty.
100
+
96
101
  ## Features
97
102
 
98
103
  ### `debug-embed`
tests/allow_missing.rs ADDED
@@ -0,0 +1,15 @@
1
+ use std::{path::PathBuf, str::FromStr};
2
+
3
+ use rust_embed::Embed;
4
+
5
+ #[derive(Embed)]
6
+ #[folder = "examples/missing/"]
7
+ #[allow_missing = true]
8
+ struct Asset;
9
+
10
+ #[test]
11
+ fn missing_is_empty() {
12
+ let path = PathBuf::from_str("./examples/missing").unwrap();
13
+ assert!(!path.exists());
14
+ assert_eq!(Asset::iter().count(), 0);
15
+ }