~repos /rust-embed

#rust#proc-macro#http

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.


7c0fc42f Mark Drobnak

2 years ago
Merge pull request #203 from BBaoVanC/static-mime-guess
.github/workflows/test.yml CHANGED
@@ -33,6 +33,8 @@ jobs:
33
33
  cargo test --test lib
34
34
  cargo test --test lib --features "debug-embed"
35
35
  cargo test --test lib --features "compression" --release
36
+ cargo test --test mime_guess --features "mime-guess"
37
+ cargo test --test mime_guess --features "mime-guess" --release
36
38
  cargo test --test interpolated_path --features "interpolate-folder-path"
37
39
  cargo test --test interpolated_path --features "interpolate-folder-path" --release
38
40
  cargo build --example basic
Cargo.toml CHANGED
@@ -56,6 +56,11 @@ name = "include_exclude"
56
56
  path = "tests/include_exclude.rs"
57
57
  required-features = ["include-exclude"]
58
58
 
59
+ [[test]]
60
+ name = "mime_guess"
61
+ path = "tests/mime_guess.rs"
62
+ required-features = ["mime-guess"]
63
+
59
64
  [dependencies]
60
65
  walkdir = "2.3.1"
61
66
  rust-embed-impl = { version = "6.3.1", path = "impl"}
@@ -79,6 +84,7 @@ sha2 = "0.10"
79
84
  debug-embed = ["rust-embed-impl/debug-embed", "rust-embed-utils/debug-embed"]
80
85
  interpolate-folder-path = ["rust-embed-impl/interpolate-folder-path"]
81
86
  compression = ["rust-embed-impl/compression", "include-flate"]
87
+ mime-guess = ["rust-embed-impl/mime-guess"]
82
88
  include-exclude = ["rust-embed-impl/include-exclude", "rust-embed-utils/include-exclude"]
83
89
  actix = ["actix-web", "mime_guess"]
84
90
  warp-ex = ["warp", "tokio", "mime_guess"]
impl/Cargo.toml CHANGED
@@ -30,4 +30,5 @@ optional = true
30
30
  debug-embed = []
31
31
  interpolate-folder-path = ["shellexpand"]
32
32
  compression = []
33
+ mime-guess = ["rust-embed-utils/mime-guess"]
33
34
  include-exclude = ["rust-embed-utils/include-exclude"]
impl/src/lib.rs CHANGED
@@ -174,6 +174,13 @@ fn embed_file(rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
174
174
  Some(last_modified) => quote! { Some(#last_modified) },
175
175
  None => quote! { None },
176
176
  };
177
+ #[cfg(feature = "mime-guess")]
178
+ let mimetype_tokens = {
179
+ let mt = file.metadata.mimetype();
180
+ quote! { , #mt }
181
+ };
182
+ #[cfg(not(feature = "mime-guess"))]
183
+ let mimetype_tokens = TokenStream2::new();
177
184
 
178
185
  let embedding_code = if cfg!(feature = "compression") {
179
186
  quote! {
@@ -192,7 +199,7 @@ fn embed_file(rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
192
199
 
193
200
  Some(rust_embed::EmbeddedFile {
194
201
  data: std::borrow::Cow::from(bytes),
195
- metadata: rust_embed::Metadata::__rust_embed_new([#(#hash),*], #last_modified)
202
+ metadata: rust_embed::Metadata::__rust_embed_new([#(#hash),*], #last_modified #mimetype_tokens)
196
203
  })
197
204
  }
198
205
  }
tests/mime_guess.rs ADDED
@@ -0,0 +1,35 @@
1
+ use rust_embed::{EmbeddedFile, RustEmbed};
2
+
3
+ #[derive(RustEmbed)]
4
+ #[folder = "examples/public/"]
5
+ struct Asset;
6
+
7
+ #[test]
8
+ fn html_mime_is_correct() {
9
+ let html_file: EmbeddedFile = Asset::get("index.html").expect("index.html exists");
10
+ assert_eq!(html_file.metadata.mimetype(), "text/html");
11
+ }
12
+
13
+ #[test]
14
+ fn css_mime_is_correct() {
15
+ let css_file: EmbeddedFile = Asset::get("main.css").expect("main.css exists");
16
+ assert_eq!(css_file.metadata.mimetype(), "text/css");
17
+ }
18
+
19
+ #[test]
20
+ fn js_mime_is_correct() {
21
+ let js_file: EmbeddedFile = Asset::get("main.js").expect("main.js exists");
22
+ assert_eq!(js_file.metadata.mimetype(), "application/javascript");
23
+ }
24
+
25
+ #[test]
26
+ fn jpg_mime_is_correct() {
27
+ let jpg_file: EmbeddedFile = Asset::get("images/flower.jpg").expect("flower.jpg exists");
28
+ assert_eq!(jpg_file.metadata.mimetype(), "image/jpeg");
29
+ }
30
+
31
+ #[test]
32
+ fn png_mime_is_correct() {
33
+ let png_file: EmbeddedFile = Asset::get("images/llama.png").expect("llama.png exists");
34
+ assert_eq!(png_file.metadata.mimetype(), "image/png");
35
+ }
utils/Cargo.toml CHANGED
@@ -14,6 +14,7 @@ edition = "2018"
14
14
  [dependencies]
15
15
  walkdir = "2.3.1"
16
16
  sha2 = "0.10.5"
17
+ mime_guess = { version = "2.0.4", optional = true }
17
18
 
18
19
  [dependencies.globset]
19
20
  version = "0.4.8"
@@ -21,4 +22,5 @@ optional = true
21
22
 
22
23
  [features]
23
24
  debug-embed = []
25
+ mime-guess = ["mime_guess"]
24
26
  include-exclude = ["globset"]
utils/src/lib.rs CHANGED
@@ -87,12 +87,19 @@ pub struct EmbeddedFile {
87
87
  pub struct Metadata {
88
88
  hash: [u8; 32],
89
89
  last_modified: Option<u64>,
90
+ #[cfg(feature = "mime-guess")]
91
+ mimetype: Cow<'static, str>,
90
92
  }
91
93
 
92
94
  impl Metadata {
93
95
  #[doc(hidden)]
94
- pub fn __rust_embed_new(hash: [u8; 32], last_modified: Option<u64>) -> Self {
96
+ pub fn __rust_embed_new(hash: [u8; 32], last_modified: Option<u64>, #[cfg(feature = "mime-guess")] mimetype: &'static str) -> Self {
97
+ Self {
98
+ hash,
95
- Self { hash, last_modified }
99
+ last_modified,
100
+ #[cfg(feature = "mime-guess")]
101
+ mimetype: mimetype.into(),
102
+ }
96
103
  }
97
104
 
98
105
  /// The SHA256 hash of the file
@@ -105,6 +112,12 @@ impl Metadata {
105
112
  pub fn last_modified(&self) -> Option<u64> {
106
113
  self.last_modified
107
114
  }
115
+
116
+ /// The mime type of the file
117
+ #[cfg(feature = "mime-guess")]
118
+ pub fn mimetype(&self) -> &str {
119
+ &self.mimetype
120
+ }
108
121
  }
109
122
 
110
123
  pub fn read_file_from_fs(file_path: &Path) -> io::Result<EmbeddedFile> {
@@ -127,11 +140,16 @@ pub fn read_file_from_fs(file_path: &Path) -> io::Result<EmbeddedFile> {
127
140
  .as_secs()
128
141
  });
129
142
 
143
+ #[cfg(feature = "mime-guess")]
144
+ let mimetype = mime_guess::from_path(file_path).first_or_octet_stream().to_string();
145
+
130
146
  Ok(EmbeddedFile {
131
147
  data,
132
148
  metadata: Metadata {
133
149
  hash,
134
150
  last_modified: source_date_epoch.or(last_modified),
151
+ #[cfg(feature = "mime-guess")]
152
+ mimetype: mimetype.into(),
135
153
  },
136
154
  })
137
155
  }