@@ -10,6 +10,7 @@ use rust_embed_utils::PathMatcher;
1010use std:: {
1111 collections:: BTreeMap ,
1212 env,
13+ io:: ErrorKind ,
1314 iter:: FromIterator ,
1415 path:: { Path , PathBuf } ,
1516} ;
@@ -135,7 +136,14 @@ fn dynamic(
135136 . map( |mut file| { file. data = :: std:: default :: Default :: default ( ) ; file } )
136137 } ) ;
137138
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" ) ;
139147 let canonical_folder_path = canonical_folder_path. to_str ( ) . expect ( "absolute folder path must be valid unicode" ) ;
140148
141149 quote ! {
@@ -339,6 +347,7 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> syn::Result<TokenStream2> {
339347 let includes = find_attribute_values ( ast, "include" ) ;
340348 let excludes = find_attribute_values ( ast, "exclude" ) ;
341349 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 ) ;
342351
343352 #[ cfg( not( feature = "include-exclude" ) ) ]
344353 if !includes. is_empty ( ) || !excludes. is_empty ( ) {
@@ -368,7 +377,7 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> syn::Result<TokenStream2> {
368377 ( None , folder_path)
369378 } ;
370379
371- if !Path :: new ( & absolute_folder_path) . exists ( ) {
380+ if !Path :: new ( & absolute_folder_path) . exists ( ) && !allow_missing {
372381 let mut message = format ! (
373382 "#[derive(RustEmbed)] folder '{}' does not exist. cwd: '{}'" ,
374383 absolute_folder_path,
@@ -397,7 +406,7 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> syn::Result<TokenStream2> {
397406 )
398407}
399408
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) ) ]
401410pub fn derive_input_object ( input : TokenStream ) -> TokenStream {
402411 let ast = parse_macro_input ! ( input as DeriveInput ) ;
403412 match impl_rust_embed ( & ast) {
0 commit comments