@@ -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
138
- let canonical_folder_path = Path :: new ( & folder_path) . canonicalize ( ) . expect ( "folder path must resolve to an absolute path" ) ;
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
+ } )
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) {
0 commit comments