~repos /rust-embed

#rust#proc-macro#http

git clone https://pyrossh.dev/repos/rust-embed.git
Discussions: https://groups.google.com/g/rust-embed-devs

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


Files changed (2) hide show
  1. impl/src/lib.rs +22 -15
  2. utils/src/lib.rs +3 -1
impl/src/lib.rs CHANGED
@@ -7,6 +7,7 @@ extern crate proc_macro;
7
7
  use proc_macro::TokenStream;
8
8
  use proc_macro2::TokenStream as TokenStream2;
9
9
  use std::{
10
+ collections::BTreeMap,
10
11
  env,
11
12
  iter::FromIterator,
12
13
  path::{Path, PathBuf},
@@ -18,13 +19,13 @@ fn embedded(
18
19
  ) -> TokenStream2 {
19
20
  extern crate rust_embed_utils;
20
21
 
21
- let mut match_values = Vec::<TokenStream2>::new();
22
+ let mut match_values = BTreeMap::new();
22
23
  let mut list_values = Vec::<String>::new();
23
24
 
24
25
  let includes: Vec<&str> = includes.iter().map(AsRef::as_ref).collect();
25
26
  let excludes: Vec<&str> = excludes.iter().map(AsRef::as_ref).collect();
26
27
  for rust_embed_utils::FileEntry { rel_path, full_canonical_path } in rust_embed_utils::get_files(absolute_folder_path.clone(), &includes, &excludes) {
27
- match_values.push(embed_file(relative_folder_path.clone(), &rel_path, &full_canonical_path));
28
+ match_values.insert(rel_path.clone(), embed_file(relative_folder_path.clone(), &rel_path, &full_canonical_path));
28
29
 
29
30
  list_values.push(if let Some(prefix) = prefix {
30
31
  format!("{}{}", prefix, rel_path)
@@ -50,17 +51,23 @@ fn embedded(
50
51
  } else {
51
52
  TokenStream2::new()
52
53
  };
53
-
54
+ let match_values = match_values.into_iter().map(|(path, bytes)| {
55
+ quote! {
56
+ (#path, #bytes),
57
+ }
58
+ });
54
59
  quote! {
55
60
  #not_debug_attr
56
61
  impl #ident {
57
62
  /// Get an embedded file and its metadata.
58
63
  pub fn get(file_path: &str) -> Option<rust_embed::EmbeddedFile> {
59
64
  #handle_prefix
60
- match file_path.replace("\\", "/").as_str() {
65
+ let key = file_path.replace("\\", "/");
66
+ const ENTRIES: &'static [(&'static str, rust_embed::EmbeddedFile)] = &[
61
- #(#match_values)*
67
+ #(#match_values)*];
68
+ let position = ENTRIES.binary_search_by_key(&key.as_str(), |entry| entry.0);
62
- _ => None,
69
+ position.ok().map(|index| ENTRIES[index].1.clone())
63
- }
70
+
64
71
  }
65
72
 
66
73
  fn names() -> std::slice::Iter<'static, &'static str> {
@@ -203,22 +210,22 @@ fn embed_file(folder_path: Option<&str>, rel_path: &str, full_canonical_path: &s
203
210
  let full_relative_path = full_relative_path.to_string_lossy();
204
211
  quote! {
205
212
  rust_embed::flate!(static FILE: [u8] from #full_relative_path);
206
- let bytes = &FILE[..];
213
+ const BYTES: &'static [u8] = FILE;
207
214
  }
208
215
  } else {
209
216
  quote! {
210
- let bytes = &include_bytes!(#full_canonical_path)[..];
217
+ const BYTES: &'static [u8] = include_bytes!(#full_canonical_path);
211
218
  }
212
219
  };
213
220
 
214
221
  quote! {
215
- #rel_path => {
222
+ {
216
- #embedding_code
223
+ #embedding_code
217
224
 
218
- Some(rust_embed::EmbeddedFile {
225
+ rust_embed::EmbeddedFile {
219
- data: std::borrow::Cow::from(bytes),
226
+ data: std::borrow::Cow::Borrowed(BYTES),
220
- metadata: rust_embed::Metadata::__rust_embed_new([#(#hash),*], #last_modified #mimetype_tokens)
227
+ metadata: rust_embed::Metadata::__rust_embed_new([#(#hash),*], #last_modified #mimetype_tokens)
221
- })
228
+ }
222
229
  }
223
230
  }
224
231
  }
utils/src/lib.rs CHANGED
@@ -78,12 +78,14 @@ pub fn get_files<'patterns>(folder_path: String, includes: &'patterns [&str], ex
78
78
  }
79
79
 
80
80
  /// A file embedded into the binary
81
+ #[derive(Clone)]
81
82
  pub struct EmbeddedFile {
82
83
  pub data: Cow<'static, [u8]>,
83
84
  pub metadata: Metadata,
84
85
  }
85
86
 
86
87
  /// Metadata about an embedded file
88
+ #[derive(Clone)]
87
89
  pub struct Metadata {
88
90
  hash: [u8; 32],
89
91
  last_modified: Option<u64>,
@@ -93,7 +95,7 @@ pub struct Metadata {
93
95
 
94
96
  impl Metadata {
95
97
  #[doc(hidden)]
96
- pub fn __rust_embed_new(hash: [u8; 32], last_modified: Option<u64>, #[cfg(feature = "mime-guess")] mimetype: &'static str) -> Self {
98
+ pub const fn __rust_embed_new(hash: [u8; 32], last_modified: Option<u64>, #[cfg(feature = "mime-guess")] mimetype: &'static str) -> Self {
97
99
  Self {
98
100
  hash,
99
101
  last_modified,