~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 +10 -6
  2. src/lib.rs +29 -0
impl/src/lib.rs CHANGED
@@ -48,8 +48,9 @@ fn generate_assets(ident: &syn::Ident, folder_path: String) -> quote::Tokens {
48
48
  fn get(&self, file_path: &str) -> Option<std::borrow::Cow<'static, [u8]>> {
49
49
  #ident::get(file_path)
50
50
  }
51
- fn iter(&self) -> Box<dyn Iterator<Item = std::borrow::Cow<'static, str>>> {
51
+ fn iter(&self) -> rust_embed::Filenames {
52
+ // the return type of iter() is unnamable, so we have to box it
52
- Box::new(#ident::iter())
53
+ rust_embed::Filenames::Dynamic(Box::new(#ident::iter()))
53
54
  }
54
55
  }
55
56
  }
@@ -83,17 +84,20 @@ fn generate_assets(ident: &syn::Ident, folder_path: String) -> quote::Tokens {
83
84
  }
84
85
  }
85
86
 
87
+ fn names() -> std::slice::Iter<'static, &'static str> {
88
+ const items: [&str; #array_len] = [#(#list_values),*];
89
+ items.iter()
90
+ }
86
91
  pub fn iter() -> impl Iterator<Item = std::borrow::Cow<'static, str>> {
87
- static items: [&str; #array_len] = [#(#list_values),*];
88
- items.iter().map(|x| std::borrow::Cow::from(*x))
92
+ Self::names().map(|x| std::borrow::Cow::from(*x))
89
93
  }
90
94
  }
91
95
  impl rust_embed::RustEmbed for #ident {
92
96
  fn get(&self, file_path: &str) -> Option<std::borrow::Cow<'static, [u8]>> {
93
97
  #ident::get(file_path)
94
98
  }
95
- fn iter(&self) -> Box<dyn Iterator<Item = std::borrow::Cow<'static, str>>> {
99
+ fn iter(&self) -> rust_embed::Filenames {
96
- Box::new(#ident::iter())
100
+ rust_embed::Filenames::Embedded(#ident::names())
97
101
  }
98
102
  }
99
103
  }
src/lib.rs CHANGED
@@ -44,3 +44,32 @@ pub trait RustEmbed {
44
44
  /// Otherwise, the files are listed from the file system on each call.
45
45
  fn iter(&self) -> Filenames;
46
46
  }
47
+
48
+ /// An iterator type over filenames.
49
+ ///
50
+ /// This enum exists for optimization purposes, to avoid boxing the iterator in
51
+ /// some cases. Do not try and match on it, as different variants will exist
52
+ /// depending on the compilation context.
53
+ pub enum Filenames {
54
+ /// Release builds use a nameable iterator type, which can be stack-allocated.
55
+ #[cfg(any(not(debug_assertions), feature = "debug-embed"))]
56
+ Embedded(std::slice::Iter<'static, &'static str>),
57
+
58
+ /// The debug iterator type is currently unnamable and still needs to be
59
+ /// boxed.
60
+ #[cfg(all(debug_assertions, not(feature = "debug-embed")))]
61
+ Dynamic(Box<dyn Iterator<Item = std::borrow::Cow<'static, str>>>),
62
+ }
63
+
64
+ impl Iterator for Filenames {
65
+ type Item = std::borrow::Cow<'static, str>;
66
+ fn next(&mut self) -> Option<Self::Item> {
67
+ match self {
68
+ #[cfg(any(not(debug_assertions), feature = "debug-embed"))]
69
+ Filenames::Embedded(names) => names.next().map(|x| std::borrow::Cow::from(*x)),
70
+
71
+ #[cfg(all(debug_assertions, not(feature = "debug-embed")))]
72
+ Filenames::Dynamic(boxed) => boxed.next(),
73
+ }
74
+ }
75
+ }