rust-embed v8.11.0

#rust#proc-macro#http

git clone https://git.pyrossh.dev/rust-embed

rust macro which loads files into the rust binary at compile time during release and loads the file from the fs during dev.


91d0d21pyrossh 2026-06-15T21:55:01+05:30
Fix mime guess host/target issue
Files changed (2) hide show
  1. impl/src/lib.rs +7 -8
  2. utils/src/lib.rs +48 -0
impl/src/lib.rs CHANGED
@@ -276,13 +276,12 @@ fn embed_file(
276
276
  };
277
277
  (last_modified, created)
278
278
  };
279
- #[cfg(feature = "mime-guess")]
279
+ // Always compute and emit the mimetype, without branching on this crate's own
280
- let mimetype_tokens = {
281
- let mt = file.metadata.mimetype();
282
- quote! { , #mt }
283
- };
284
- #[cfg(not(feature = "mime-guess"))]
280
+ // `mime-guess` feature. This crate is a proc-macro compiled for the host, so
281
+ // its features are resolved independently of the target the generated code is
282
+ // compiled into. The decision of whether to keep the mimetype is made
283
+ // target-side by the `__rust_embed_metadata!` macro in `rust-embed-utils`.
285
- let mimetype_tokens = TokenStream2::new();
284
+ let mimetype = rust_embed_utils::_mimetype_of(Path::new(full_canonical_path));
286
285
 
287
286
  let embedding_code = if metadata_only {
288
287
  quote! {
@@ -312,7 +311,7 @@ fn embed_file(
312
311
 
313
312
  #crate_path::EmbeddedFile {
314
313
  data: ::std::borrow::Cow::Borrowed(&BYTES),
315
- metadata: #crate_path::Metadata::__rust_embed_new([#(#hash),*], #last_modified, #created #mimetype_tokens)
314
+ metadata: #crate_path::utils::__rust_embed_metadata!([#(#hash),*], #last_modified, #created, #mimetype)
316
315
  }
317
316
  }
318
317
  })
utils/src/lib.rs CHANGED
@@ -54,6 +54,54 @@ pub struct Metadata {
54
54
  mimetype: Cow<'static, str>,
55
55
  }
56
56
 
57
+ /// Constructs a [`Metadata`] from tokens emitted by the derive macro.
58
+ ///
59
+ /// The derive macro (`rust-embed-impl`) is a proc-macro and is therefore always
60
+ /// compiled for the *host*, where its `mime-guess` feature is resolved
61
+ /// independently of the *target* that the generated code is compiled into. It
62
+ /// must not branch on its own `#[cfg(feature = "mime-guess")]`, since that
63
+ /// reflects the host rather than the target. Instead it unconditionally emits
64
+ /// all four arguments (including a mimetype string) and defers to this macro,
65
+ /// which *is* compiled for the target and so discards the mimetype when
66
+ /// `mime-guess` is disabled there.
67
+ #[cfg(feature = "mime-guess")]
68
+ #[doc(hidden)]
69
+ #[macro_export]
70
+ macro_rules! __rust_embed_metadata {
71
+ ($hash:expr, $last_modified:expr, $created:expr, $mimetype:expr $(,)?) => {
72
+ $crate::Metadata::__rust_embed_new($hash, $last_modified, $created, $mimetype)
73
+ };
74
+ }
75
+
76
+ /// See the `mime-guess` variant above. This variant drops the mimetype token.
77
+ #[cfg(not(feature = "mime-guess"))]
78
+ #[doc(hidden)]
79
+ #[macro_export]
80
+ macro_rules! __rust_embed_metadata {
81
+ ($hash:expr, $last_modified:expr, $created:expr, $mimetype:expr $(,)?) => {
82
+ $crate::Metadata::__rust_embed_new($hash, $last_modified, $created)
83
+ };
84
+ }
85
+
86
+ /// Computes the mimetype of a file at build time.
87
+ ///
88
+ /// This is always available (regardless of the `mime-guess` feature) so that
89
+ /// the derive macro can unconditionally produce a mimetype token without using
90
+ /// `#[cfg(…)]`. The token is only ever used by [`__rust_embed_metadata`] when
91
+ /// the target enables `mime-guess`; otherwise the empty string returned here is
92
+ /// discarded by the macro.
93
+ #[doc(hidden)]
94
+ pub fn _mimetype_of(_path: &Path) -> String {
95
+ #[cfg(feature = "mime-guess")]
96
+ {
97
+ mime_guess::from_path(_path).first_or_octet_stream().to_string()
98
+ }
99
+ #[cfg(not(feature = "mime-guess"))]
100
+ {
101
+ String::new()
102
+ }
103
+ }
104
+
57
105
  impl Metadata {
58
106
  #[doc(hidden)]
59
107
  pub const fn __rust_embed_new(