Skip to content

Commit 769f661

Browse files
authored
Merge pull request #256 from lirannl/master
Add allow_missing option to derive macro
2 parents 2e69081 + 5655966 commit 769f661

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

impl/src/lib.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rust_embed_utils::PathMatcher;
1010
use 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))]
401410
pub fn derive_input_object(input: TokenStream) -> TokenStream {
402411
let ast = parse_macro_input!(input as DeriveInput);
403412
match impl_rust_embed(&ast) {

readme.md

+5
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ be included in the file paths returned by `iter`.
9393
You can add `#[metadata_only = true]` to the `RustEmbed` struct to exclude file contents from the
9494
binary. Only file paths and metadata will be embedded.
9595

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+
96101
## Features
97102

98103
### `debug-embed`

tests/allow_missing.rs

+15
Original file line numberDiff line numberDiff line change
@@ -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+
}

0 commit comments

Comments
 (0)