@@ -17,7 +17,7 @@ use syn::{parse_macro_input, Data, DeriveInput, Expr, ExprLit, Fields, Lit, Meta
17
17
18
18
fn embedded (
19
19
ident : & syn:: Ident , relative_folder_path : Option < & str > , absolute_folder_path : String , prefix : Option < & str > , includes : & [ String ] , excludes : & [ String ] ,
20
- metadata_only : bool ,
20
+ metadata_only : bool , crate_path : & syn :: Path ,
21
21
) -> syn:: Result < TokenStream2 > {
22
22
extern crate rust_embed_utils;
23
23
@@ -30,7 +30,7 @@ fn embedded(
30
30
for rust_embed_utils:: FileEntry { rel_path, full_canonical_path } in rust_embed_utils:: get_files ( absolute_folder_path. clone ( ) , matcher) {
31
31
match_values. insert (
32
32
rel_path. clone ( ) ,
33
- embed_file ( relative_folder_path, ident, & rel_path, & full_canonical_path, metadata_only) ?,
33
+ embed_file ( relative_folder_path, ident, & rel_path, & full_canonical_path, metadata_only, crate_path ) ?,
34
34
) ;
35
35
36
36
list_values. push ( if let Some ( prefix) = prefix {
@@ -63,9 +63,9 @@ fn embedded(
63
63
}
64
64
} ) ;
65
65
let value_type = if cfg ! ( feature = "compression" ) {
66
- quote ! { fn ( ) -> rust_embed :: EmbeddedFile }
66
+ quote ! { fn ( ) -> #crate_path :: EmbeddedFile }
67
67
} else {
68
- quote ! { rust_embed :: EmbeddedFile }
68
+ quote ! { #crate_path :: EmbeddedFile }
69
69
} ;
70
70
let get_value = if cfg ! ( feature = "compression" ) {
71
71
quote ! { |idx| ( ENTRIES [ idx] . 1 ) ( ) }
@@ -76,7 +76,7 @@ fn embedded(
76
76
#not_debug_attr
77
77
impl #ident {
78
78
/// Get an embedded file and its metadata.
79
- pub fn get( file_path: & str ) -> :: std:: option:: Option <rust_embed :: EmbeddedFile > {
79
+ pub fn get( file_path: & str ) -> :: std:: option:: Option <#crate_path :: EmbeddedFile > {
80
80
#handle_prefix
81
81
let key = file_path. replace( "\\ " , "/" ) ;
82
82
const ENTRIES : & ' static [ ( & ' static str , #value_type) ] = & [
@@ -98,18 +98,20 @@ fn embedded(
98
98
}
99
99
100
100
#not_debug_attr
101
- impl rust_embed :: RustEmbed for #ident {
102
- fn get( file_path: & str ) -> :: std:: option:: Option <rust_embed :: EmbeddedFile > {
101
+ impl #crate_path :: RustEmbed for #ident {
102
+ fn get( file_path: & str ) -> :: std:: option:: Option <#crate_path :: EmbeddedFile > {
103
103
#ident:: get( file_path)
104
104
}
105
- fn iter( ) -> rust_embed :: Filenames {
106
- rust_embed :: Filenames :: Embedded ( #ident:: names( ) )
105
+ fn iter( ) -> #crate_path :: Filenames {
106
+ #crate_path :: Filenames :: Embedded ( #ident:: names( ) )
107
107
}
108
108
}
109
109
} )
110
110
}
111
111
112
- fn dynamic ( ident : & syn:: Ident , folder_path : String , prefix : Option < & str > , includes : & [ String ] , excludes : & [ String ] , metadata_only : bool ) -> TokenStream2 {
112
+ fn dynamic (
113
+ ident : & syn:: Ident , folder_path : String , prefix : Option < & str > , includes : & [ String ] , excludes : & [ String ] , metadata_only : bool , crate_path : & syn:: Path ,
114
+ ) -> TokenStream2 {
113
115
let ( handle_prefix, map_iter) = if let :: std:: option:: Option :: Some ( prefix) = prefix {
114
116
(
115
117
quote ! { let file_path = file_path. strip_prefix( #prefix) ?; } ,
@@ -141,14 +143,14 @@ fn dynamic(ident: &syn::Ident, folder_path: String, prefix: Option<&str>, includ
141
143
impl #ident {
142
144
143
145
144
- fn matcher( ) -> :: rust_embed :: utils:: PathMatcher {
146
+ fn matcher( ) -> #crate_path :: utils:: PathMatcher {
145
147
#declare_includes
146
148
#declare_excludes
147
- static PATH_MATCHER : :: std:: sync:: OnceLock <:: rust_embed :: utils:: PathMatcher > = :: std:: sync:: OnceLock :: new( ) ;
148
- PATH_MATCHER . get_or_init( || rust_embed :: utils:: PathMatcher :: new( INCLUDES , EXCLUDES ) ) . clone( )
149
+ static PATH_MATCHER : :: std:: sync:: OnceLock <#crate_path :: utils:: PathMatcher > = :: std:: sync:: OnceLock :: new( ) ;
150
+ PATH_MATCHER . get_or_init( || #crate_path :: utils:: PathMatcher :: new( INCLUDES , EXCLUDES ) ) . clone( )
149
151
}
150
152
/// Get an embedded file and its metadata.
151
- pub fn get( file_path: & str ) -> :: std:: option:: Option <rust_embed :: EmbeddedFile > {
153
+ pub fn get( file_path: & str ) -> :: std:: option:: Option <#crate_path :: EmbeddedFile > {
152
154
#handle_prefix
153
155
154
156
let rel_file_path = file_path. replace( "\\ " , "/" ) ;
@@ -171,7 +173,7 @@ fn dynamic(ident: &syn::Ident, folder_path: String, prefix: Option<&str>, includ
171
173
}
172
174
let path_matcher = Self :: matcher( ) ;
173
175
if path_matcher. is_path_included( & rel_file_path) {
174
- rust_embed :: utils:: read_file_from_fs( & canonical_file_path) . ok( ) #strip_contents
176
+ #crate_path :: utils:: read_file_from_fs( & canonical_file_path) . ok( ) #strip_contents
175
177
} else {
176
178
:: std:: option:: Option :: None
177
179
}
@@ -182,27 +184,27 @@ fn dynamic(ident: &syn::Ident, folder_path: String, prefix: Option<&str>, includ
182
184
use :: std:: path:: Path ;
183
185
184
186
185
- rust_embed :: utils:: get_files( :: std:: string:: String :: from( #folder_path) , Self :: matcher( ) )
187
+ #crate_path :: utils:: get_files( :: std:: string:: String :: from( #folder_path) , Self :: matcher( ) )
186
188
. map( |e| #map_iter)
187
189
}
188
190
}
189
191
190
192
#[ cfg( debug_assertions) ]
191
- impl rust_embed :: RustEmbed for #ident {
192
- fn get( file_path: & str ) -> :: std:: option:: Option <rust_embed :: EmbeddedFile > {
193
+ impl #crate_path :: RustEmbed for #ident {
194
+ fn get( file_path: & str ) -> :: std:: option:: Option <#crate_path :: EmbeddedFile > {
193
195
#ident:: get( file_path)
194
196
}
195
- fn iter( ) -> rust_embed :: Filenames {
197
+ fn iter( ) -> #crate_path :: Filenames {
196
198
// the return type of iter() is unnamable, so we have to box it
197
- rust_embed :: Filenames :: Dynamic ( :: std:: boxed:: Box :: new( #ident:: iter( ) ) )
199
+ #crate_path :: Filenames :: Dynamic ( :: std:: boxed:: Box :: new( #ident:: iter( ) ) )
198
200
}
199
201
}
200
202
}
201
203
}
202
204
203
205
fn generate_assets (
204
206
ident : & syn:: Ident , relative_folder_path : Option < & str > , absolute_folder_path : String , prefix : Option < String > , includes : Vec < String > , excludes : Vec < String > ,
205
- metadata_only : bool ,
207
+ metadata_only : bool , crate_path : & syn :: Path ,
206
208
) -> syn:: Result < TokenStream2 > {
207
209
let embedded_impl = embedded (
208
210
ident,
@@ -212,20 +214,23 @@ fn generate_assets(
212
214
& includes,
213
215
& excludes,
214
216
metadata_only,
217
+ crate_path,
215
218
) ;
216
219
if cfg ! ( feature = "debug-embed" ) {
217
220
return embedded_impl;
218
221
}
219
222
let embedded_impl = embedded_impl?;
220
- let dynamic_impl = dynamic ( ident, absolute_folder_path, prefix. as_deref ( ) , & includes, & excludes, metadata_only) ;
223
+ let dynamic_impl = dynamic ( ident, absolute_folder_path, prefix. as_deref ( ) , & includes, & excludes, metadata_only, crate_path ) ;
221
224
222
225
Ok ( quote ! {
223
226
#embedded_impl
224
227
#dynamic_impl
225
228
} )
226
229
}
227
230
228
- fn embed_file ( folder_path : Option < & str > , ident : & syn:: Ident , rel_path : & str , full_canonical_path : & str , metadata_only : bool ) -> syn:: Result < TokenStream2 > {
231
+ fn embed_file (
232
+ folder_path : Option < & str > , ident : & syn:: Ident , rel_path : & str , full_canonical_path : & str , metadata_only : bool , crate_path : & syn:: Path ,
233
+ ) -> syn:: Result < TokenStream2 > {
229
234
let file = rust_embed_utils:: read_file_from_fs ( Path :: new ( full_canonical_path) ) . expect ( "File should be readable" ) ;
230
235
let hash = file. metadata . sha256_hash ( ) ;
231
236
let last_modified = match file. metadata . last_modified ( ) {
@@ -254,7 +259,7 @@ fn embed_file(folder_path: Option<&str>, ident: &syn::Ident, rel_path: &str, ful
254
259
let full_relative_path = PathBuf :: from_iter ( [ folder_path, rel_path] ) ;
255
260
let full_relative_path = full_relative_path. to_string_lossy ( ) ;
256
261
quote ! {
257
- rust_embed :: flate!( static BYTES : [ u8 ] from #full_relative_path) ;
262
+ #crate_path :: flate!( static BYTES : [ u8 ] from #full_relative_path) ;
258
263
}
259
264
} else {
260
265
quote ! {
@@ -270,9 +275,9 @@ fn embed_file(folder_path: Option<&str>, ident: &syn::Ident, rel_path: &str, ful
270
275
#closure_args {
271
276
#embedding_code
272
277
273
- rust_embed :: EmbeddedFile {
278
+ #crate_path :: EmbeddedFile {
274
279
data: :: std:: borrow:: Cow :: Borrowed ( & BYTES ) ,
275
- metadata: rust_embed :: Metadata :: __rust_embed_new( [ #( #hash) , * ] , #last_modified, #created #mimetype_tokens)
280
+ metadata: #crate_path :: Metadata :: __rust_embed_new( [ #( #hash) , * ] , #last_modified, #created #mimetype_tokens)
276
281
}
277
282
}
278
283
} )
@@ -317,6 +322,11 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> syn::Result<TokenStream2> {
317
322
_ => return Err ( syn:: Error :: new_spanned ( ast, "RustEmbed can only be derived for unit structs" ) ) ,
318
323
} ;
319
324
325
+ let crate_path: syn:: Path = find_attribute_values ( ast, "crate_path" )
326
+ . last ( )
327
+ . map ( |v| syn:: parse_str ( & v) . unwrap ( ) )
328
+ . unwrap_or_else ( || syn:: parse_str ( "rust_embed" ) . unwrap ( ) ) ;
329
+
320
330
let mut folder_paths = find_attribute_values ( ast, "folder" ) ;
321
331
if folder_paths. len ( ) != 1 {
322
332
return Err ( syn:: Error :: new_spanned (
@@ -384,10 +394,11 @@ fn impl_rust_embed(ast: &syn::DeriveInput) -> syn::Result<TokenStream2> {
384
394
includes,
385
395
excludes,
386
396
metadata_only,
397
+ & crate_path,
387
398
)
388
399
}
389
400
390
- #[ proc_macro_derive( RustEmbed , attributes( folder, prefix, include, exclude, metadata_only) ) ]
401
+ #[ proc_macro_derive( RustEmbed , attributes( folder, prefix, include, exclude, metadata_only, crate_path ) ) ]
391
402
pub fn derive_input_object ( input : TokenStream ) -> TokenStream {
392
403
let ast = parse_macro_input ! ( input as DeriveInput ) ;
393
404
match impl_rust_embed ( & ast) {
0 commit comments