~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.
83eaed49
—
Peter John 4 years ago
Merge pull request #125 from djmarcin/master
- impl/src/lib.rs +73 -46
- utils/src/lib.rs +1 -0
impl/src/lib.rs
CHANGED
|
@@ -7,9 +7,62 @@ use proc_macro::TokenStream;
|
|
|
7
7
|
use std::{env, path::Path};
|
|
8
8
|
use syn::{export::TokenStream2, Data, DeriveInput, Fields, Lit, Meta};
|
|
9
9
|
|
|
10
|
-
#[cfg(all(debug_assertions, not(feature = "debug-embed")))]
|
|
11
|
-
fn
|
|
10
|
+
fn embedded(ident: &syn::Ident, folder_path: String) -> TokenStream2 {
|
|
11
|
+
extern crate rust_embed_utils;
|
|
12
|
+
|
|
13
|
+
let mut match_values = Vec::<TokenStream2>::new();
|
|
14
|
+
let mut list_values = Vec::<String>::new();
|
|
15
|
+
|
|
16
|
+
for rust_embed_utils::FileEntry { rel_path, full_canonical_path } in rust_embed_utils::get_files(folder_path) {
|
|
17
|
+
match_values.push(embed_file(&rel_path, &full_canonical_path));
|
|
18
|
+
list_values.push(rel_path);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let array_len = list_values.len();
|
|
22
|
+
|
|
23
|
+
// If debug-embed is on, unconditionally include the code below. Otherwise,
|
|
24
|
+
// make it conditional on cfg(not(debug_assertions)).
|
|
25
|
+
let not_debug_attr = if cfg!(feature = "debug-embed") {
|
|
26
|
+
quote! {}
|
|
27
|
+
} else {
|
|
28
|
+
quote! { #[cfg(not(debug_assertions))]}
|
|
29
|
+
};
|
|
30
|
+
|
|
12
31
|
quote! {
|
|
32
|
+
#not_debug_attr
|
|
33
|
+
impl #ident {
|
|
34
|
+
pub fn get(file_path: &str) -> Option<std::borrow::Cow<'static, [u8]>> {
|
|
35
|
+
match file_path.replace("\\", "/").as_str() {
|
|
36
|
+
#(#match_values)*
|
|
37
|
+
_ => None,
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fn names() -> std::slice::Iter<'static, &'static str> {
|
|
42
|
+
const items: [&str; #array_len] = [#(#list_values),*];
|
|
43
|
+
items.iter()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
pub fn iter() -> impl Iterator<Item = std::borrow::Cow<'static, str>> {
|
|
47
|
+
Self::names().map(|x| std::borrow::Cow::from(*x))
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#not_debug_attr
|
|
52
|
+
impl rust_embed::RustEmbed for #ident {
|
|
53
|
+
fn get(file_path: &str) -> Option<std::borrow::Cow<'static, [u8]>> {
|
|
54
|
+
#ident::get(file_path)
|
|
55
|
+
}
|
|
56
|
+
fn iter() -> rust_embed::Filenames {
|
|
57
|
+
rust_embed::Filenames::Embedded(#ident::names())
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
fn dynamic(ident: &syn::Ident, folder_path: String) -> TokenStream2 {
|
|
64
|
+
quote! {
|
|
65
|
+
#[cfg(debug_assertions)]
|
|
13
66
|
impl #ident {
|
|
14
67
|
pub fn get(file_path: &str) -> Option<std::borrow::Cow<'static, [u8]>> {
|
|
15
68
|
use std::fs;
|
|
@@ -29,6 +82,8 @@ fn generate_assets(ident: &syn::Ident, folder_path: String) -> TokenStream2 {
|
|
|
29
82
|
rust_embed::utils::get_files(String::from(#folder_path)).map(|e| std::borrow::Cow::from(e.rel_path))
|
|
30
83
|
}
|
|
31
84
|
}
|
|
85
|
+
|
|
86
|
+
#[cfg(debug_assertions)]
|
|
32
87
|
impl rust_embed::RustEmbed for #ident {
|
|
33
88
|
fn get(file_path: &str) -> Option<std::borrow::Cow<'static, [u8]>> {
|
|
34
89
|
#ident::get(file_path)
|
|
@@ -41,7 +96,21 @@ fn generate_assets(ident: &syn::Ident, folder_path: String) -> TokenStream2 {
|
|
|
41
96
|
}
|
|
42
97
|
}
|
|
43
98
|
|
|
99
|
+
fn generate_assets(ident: &syn::Ident, folder_path: String) -> TokenStream2 {
|
|
100
|
+
let embedded_impl = embedded(ident, folder_path.clone());
|
|
101
|
+
if cfg!(feature = "debug-embed") {
|
|
102
|
+
return embedded_impl;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let dynamic_impl = dynamic(ident, folder_path);
|
|
106
|
+
|
|
107
|
+
quote! {
|
|
108
|
+
#embedded_impl
|
|
109
|
+
#dynamic_impl
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
44
|
-
#[cfg(
|
|
113
|
+
#[cfg(not(feature = "compression"))]
|
|
45
114
|
fn embed_file(rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
|
|
46
115
|
quote! {
|
|
47
116
|
#rel_path => {
|
|
@@ -51,7 +120,7 @@ fn embed_file(rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
|
|
|
51
120
|
}
|
|
52
121
|
}
|
|
53
122
|
|
|
54
|
-
#[cfg(
|
|
123
|
+
#[cfg(feature = "compression")]
|
|
55
124
|
fn embed_file(rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
|
|
56
125
|
quote! {
|
|
57
126
|
#rel_path => {
|
|
@@ -63,48 +132,6 @@ fn embed_file(rel_path: &str, full_canonical_path: &str) -> TokenStream2 {
|
|
|
63
132
|
}
|
|
64
133
|
}
|
|
65
134
|
|
|
66
|
-
#[cfg(any(not(debug_assertions), feature = "debug-embed"))]
|
|
67
|
-
fn generate_assets(ident: &syn::Ident, folder_path: String) -> TokenStream2 {
|
|
68
|
-
extern crate rust_embed_utils;
|
|
69
|
-
|
|
70
|
-
let mut match_values = Vec::<TokenStream2>::new();
|
|
71
|
-
let mut list_values = Vec::<String>::new();
|
|
72
|
-
|
|
73
|
-
for rust_embed_utils::FileEntry { rel_path, full_canonical_path } in rust_embed_utils::get_files(folder_path) {
|
|
74
|
-
match_values.push(embed_file(&rel_path, &full_canonical_path));
|
|
75
|
-
list_values.push(rel_path);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
let array_len = list_values.len();
|
|
79
|
-
|
|
80
|
-
quote! {
|
|
81
|
-
impl #ident {
|
|
82
|
-
pub fn get(file_path: &str) -> Option<std::borrow::Cow<'static, [u8]>> {
|
|
83
|
-
match file_path.replace("\\", "/").as_str() {
|
|
84
|
-
#(#match_values)*
|
|
85
|
-
_ => None,
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
fn names() -> std::slice::Iter<'static, &'static str> {
|
|
90
|
-
const items: [&str; #array_len] = [#(#list_values),*];
|
|
91
|
-
items.iter()
|
|
92
|
-
}
|
|
93
|
-
pub fn iter() -> impl Iterator<Item = std::borrow::Cow<'static, str>> {
|
|
94
|
-
Self::names().map(|x| std::borrow::Cow::from(*x))
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
impl rust_embed::RustEmbed for #ident {
|
|
98
|
-
fn get(file_path: &str) -> Option<std::borrow::Cow<'static, [u8]>> {
|
|
99
|
-
#ident::get(file_path)
|
|
100
|
-
}
|
|
101
|
-
fn iter() -> rust_embed::Filenames {
|
|
102
|
-
rust_embed::Filenames::Embedded(#ident::names())
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
135
|
fn impl_rust_embed(ast: &syn::DeriveInput) -> TokenStream2 {
|
|
109
136
|
match ast.data {
|
|
110
137
|
Data::Struct(ref data) => match data.fields {
|
utils/src/lib.rs
CHANGED
|
@@ -7,6 +7,7 @@ pub struct FileEntry {
|
|
|
7
7
|
#[cfg_attr(all(debug_assertions, not(feature = "debug-embed")), allow(unused))]
|
|
8
8
|
pub fn get_files(folder_path: String) -> impl Iterator<Item = FileEntry> {
|
|
9
9
|
walkdir::WalkDir::new(&folder_path)
|
|
10
|
+
.follow_links(true)
|
|
10
11
|
.into_iter()
|
|
11
12
|
.filter_map(|e| e.ok())
|
|
12
13
|
.filter(|e| e.file_type().is_file())
|