~repos /rust-embed
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.
fd159578
—
Tangent 128 6 years ago
Optimization: don't box iterators in release mode
- impl/src/lib.rs +10 -6
- 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) ->
|
|
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
|
-
|
|
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) ->
|
|
99
|
+
fn iter(&self) -> rust_embed::Filenames {
|
|
96
|
-
|
|
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
|
+
}
|