~repos /rust-embed

#rust#proc-macro#http

git clone https://pyrossh.dev/repos/rust-embed.git
Discussions: https://groups.google.com/g/rust-embed-devs

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

10 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
+ }