~repos /rust-embed
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.
826d67fb
—
Piotr Osiewicz 2 years ago
Pass relative paths to include_flate. Disallow use of absolute paths with compression feature on.
- impl/src/lib.rs +40 -18
impl/src/lib.rs
CHANGED
|
@@ -6,10 +6,16 @@ extern crate proc_macro;
|
|
|
6
6
|
|
|
7
7
|
use proc_macro::TokenStream;
|
|
8
8
|
use proc_macro2::TokenStream as TokenStream2;
|
|
9
|
+
use std::{
|
|
10
|
+
env,
|
|
11
|
+
iter::FromIterator,
|
|
9
|
-
|
|
12
|
+
path::{Path, PathBuf},
|
|
13
|
+
};
|
|
10
14
|
use syn::{Data, DeriveInput, Expr, ExprLit, Fields, Lit, Meta, MetaNameValue};
|
|
11
15
|
|
|
16
|
+
fn embedded(
|
|
12
|
-
|
|
17
|
+
ident: &syn::Ident, relative_folder_path: Option<&str>, absolute_folder_path: String, prefix: Option<&str>, includes: &[String], excludes: &[String],
|
|
18
|
+
) -> TokenStream2 {
|
|
13
19
|
extern crate rust_embed_utils;
|
|
14
20
|
|
|
15
21
|
let mut match_values = Vec::<TokenStream2>::new();
|
|
@@ -17,8 +23,8 @@ fn embedded(ident: &syn::Ident, folder_path: String, prefix: Option<&str>, inclu
|
|
|
17
23
|
|
|
18
24
|
let includes: Vec<&str> = includes.iter().map(AsRef::as_ref).collect();
|
|
19
25
|
let excludes: Vec<&str> = excludes.iter().map(AsRef::as_ref).collect();
|
|
20
|
-
for rust_embed_utils::FileEntry { rel_path, full_canonical_path } in rust_embed_utils::get_files(
|
|
26
|
+
for rust_embed_utils::FileEntry { rel_path, full_canonical_path } in rust_embed_utils::get_files(absolute_folder_path.clone(), &includes, &excludes) {
|
|
21
|
-
match_values.push(embed_file(&rel_path, &full_canonical_path));
|
|
27
|
+
match_values.push(embed_file(relative_folder_path.clone(), &rel_path, &full_canonical_path));
|
|
22
28
|
|
|
23
29
|
list_values.push(if let Some(prefix) = prefix {
|
|
24
30
|
format!("{}{}", prefix, rel_path)
|
|
@@ -153,13 +159,22 @@ fn dynamic(ident: &syn::Ident, folder_path: String, prefix: Option<&str>, includ
|
|
|
153
159
|
}
|
|
154
160
|
}
|
|
155
161
|
|
|
162
|
+
fn generate_assets(
|
|
156
|
-
|
|
163
|
+
ident: &syn::Ident, relative_folder_path: Option<&str>, absolute_folder_path: String, prefix: Option<String>, includes: Vec<String>, excludes: Vec<String>,
|
|
164
|
+
) -> TokenStream2 {
|
|
157
|
-
let embedded_impl = embedded(
|
|
165
|
+
let embedded_impl = embedded(
|
|
166
|
+
ident,
|
|
167
|
+
relative_folder_path,
|
|
168
|
+
absolute_folder_path.clone(),
|
|
169
|
+
prefix.as_deref(),
|
|
170
|
+
&includes,
|
|
171
|
+
&excludes,
|
|
172
|
+
);
|
|
158
173
|
if cfg!(feature = "debug-embed") {
|
|
159
174
|
return embedded_impl;
|
|
160
175
|
}
|
|
161
176
|
|
|
162
|
-
let dynamic_impl = dynamic(ident,
|
|
177
|
+
let dynamic_impl = dynamic(ident, absolute_folder_path, prefix.as_deref(), &includes, &excludes);
|
|
163
178
|
|
|
164
179
|
quote! {
|
|
165
180
|
#embedded_impl
|
|
@@ -167,7 +182,7 @@ fn generate_assets(ident: &syn::Ident, folder_path: String, prefix: Option<Strin
|
|
|
167
182
|
}
|
|
168
183
|
}
|
|
169
184
|
|
|
170
|
-
fn embed_file(rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
|
|
185
|
+
fn embed_file(folder_path: Option<&str>, rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
|
|
171
186
|
let file = rust_embed_utils::read_file_from_fs(Path::new(full_canonical_path)).expect("File should be readable");
|
|
172
187
|
let hash = file.metadata.sha256_hash();
|
|
173
188
|
let last_modified = match file.metadata.last_modified() {
|
|
@@ -183,8 +198,11 @@ fn embed_file(rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
|
|
|
183
198
|
let mimetype_tokens = TokenStream2::new();
|
|
184
199
|
|
|
185
200
|
let embedding_code = if cfg!(feature = "compression") {
|
|
201
|
+
// Print some debugging information
|
|
202
|
+
let full_relative_path = PathBuf::from_iter([folder_path.expect("folder_path must be provided under `compression` feature"), rel_path]);
|
|
203
|
+
let full_relative_path = full_relative_path.to_string_lossy();
|
|
186
204
|
quote! {
|
|
187
|
-
rust_embed::flate!(static FILE: [u8] from #
|
|
205
|
+
rust_embed::flate!(static FILE: [u8] from #full_relative_path);
|
|
188
206
|
let bytes = &FILE[..];
|
|
189
207
|
}
|
|
190
208
|
} else {
|
|
@@ -249,26 +267,30 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> TokenStream2 {
|
|
|
249
267
|
let folder_path = shellexpand::full(&folder_path).unwrap().to_string();
|
|
250
268
|
|
|
251
269
|
// Base relative paths on the Cargo.toml location
|
|
252
|
-
let
|
|
270
|
+
let (relative_path, absolute_folder_path) = if Path::new(&folder_path).is_relative() {
|
|
253
|
-
Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap())
|
|
271
|
+
let absolute_path = Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap())
|
|
254
|
-
.join(folder_path)
|
|
272
|
+
.join(&folder_path)
|
|
255
273
|
.to_str()
|
|
256
274
|
.unwrap()
|
|
257
|
-
.to_owned()
|
|
275
|
+
.to_owned();
|
|
276
|
+
(Some(folder_path.clone()), absolute_path)
|
|
258
277
|
} else {
|
|
278
|
+
if cfg!(feature = "compression") {
|
|
279
|
+
panic!("`folder` must be a relative path under `compression` feature.")
|
|
280
|
+
}
|
|
259
|
-
folder_path
|
|
281
|
+
(None, folder_path)
|
|
260
282
|
};
|
|
261
283
|
|
|
262
|
-
if !Path::new(&
|
|
284
|
+
if !Path::new(&absolute_folder_path).exists() {
|
|
263
285
|
let mut message = format!(
|
|
264
286
|
"#[derive(RustEmbed)] folder '{}' does not exist. cwd: '{}'",
|
|
265
|
-
|
|
287
|
+
absolute_folder_path,
|
|
266
288
|
std::env::current_dir().unwrap().to_str().unwrap()
|
|
267
289
|
);
|
|
268
290
|
|
|
269
291
|
// Add a message about the interpolate-folder-path feature if the path may
|
|
270
292
|
// include a variable
|
|
271
|
-
if
|
|
293
|
+
if absolute_folder_path.contains('$') && cfg!(not(feature = "interpolate-folder-path")) {
|
|
272
294
|
message += "\nA variable has been detected. RustEmbed can expand variables \
|
|
273
295
|
when the `interpolate-folder-path` feature is enabled.";
|
|
274
296
|
}
|
|
@@ -276,7 +298,7 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> TokenStream2 {
|
|
|
276
298
|
panic!("{}", message);
|
|
277
299
|
};
|
|
278
300
|
|
|
279
|
-
generate_assets(&ast.ident,
|
|
301
|
+
generate_assets(&ast.ident, relative_path.as_deref(), absolute_folder_path, prefix, includes, excludes)
|
|
280
302
|
}
|
|
281
303
|
|
|
282
304
|
#[proc_macro_derive(RustEmbed, attributes(folder, prefix, include, exclude))]
|