~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.


83eaed49 Peter John

4 years ago
Merge pull request #125 from djmarcin/master
Files changed (2) hide show
  1. impl/src/lib.rs +73 -46
  2. 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 generate_assets(ident: &syn::Ident, folder_path: String) -> TokenStream2 {
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(all(not(feature = "compression"), any(not(debug_assertions), feature = "debug-embed")))]
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(all(feature = "compression", any(not(debug_assertions), feature = "debug-embed")))]
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())