~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 (7) hide show
  1. Cargo.toml +2 -2
  2. changelog.md +12 -0
  3. examples/actix.rs +8 -3
  4. examples/rocket.rs +10 -4
  5. impl/Cargo.toml +1 -1
  6. impl/src/lib.rs +14 -11
  7. readme.md +5 -5
Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rust-embed"
3
- version = "4.1.0"
3
+ version = "4.2.0"
4
4
  description = "Rust Custom Derive Macro which loads files into the rust binary at compile time during release and loads the file from the fs during dev"
5
5
  readme = "readme.md"
6
6
  documentation = "https://docs.rs/rust-embed"
@@ -12,7 +12,7 @@ authors = ["pyros2097 <pyros2097@gmail.com>"]
12
12
 
13
13
  [dependencies]
14
14
  walkdir = "2.1.4"
15
- rust-embed-impl = { version = "4.1.0", path = "impl"}
15
+ rust-embed-impl = { version = "4.2.0", path = "impl"}
16
16
 
17
17
  actix-web = { version = "0.7", optional = true }
18
18
  mime_guess = { version = "2.0.0-alpha.6", optional = true }
changelog.md CHANGED
@@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6
6
 
7
7
  Thanks to [Mcat12](https://github.com/Mcat12) for the changelog.
8
8
 
9
+ ## [4.2.0] - 2018-12-02
10
+ ### Changed
11
+ - return `Cow<'static, [u8]>` to preserve static lifetime
12
+
13
+ ## [4.1.0] - 2018-10-24
14
+ ### Added
15
+ - `iter()` method to list files
16
+
17
+ ## [4.0.0] - 2018-10-11
18
+ ### Changed
19
+ - avoid vector allocation by returning `impl AsRef<[u8]>`
20
+
9
21
  ## [3.0.2] - 2018-09-05
10
22
  ### Added
11
23
  - appveyor for testing on windows
examples/actix.rs CHANGED
@@ -6,6 +6,7 @@ extern crate mime_guess;
6
6
  use actix_web::http::Method;
7
7
  use actix_web::{server, App, Body, HttpRequest, HttpResponse};
8
8
  use mime_guess::guess_mime_type;
9
+ use std::borrow::Cow;
9
10
 
10
11
  #[derive(RustEmbed)]
11
12
  #[folder = "examples/public/"]
@@ -13,9 +14,13 @@ struct Asset;
13
14
 
14
15
  fn handle_embedded_file(path: &str) -> HttpResponse {
15
16
  match Asset::get(path) {
16
- Some(content) => HttpResponse::Ok()
17
+ Some(content) => {
18
+ let body: Body = match content {
19
+ Cow::Borrowed(bytes) => bytes.into(),
20
+ Cow::Owned(bytes) => bytes.into(),
21
+ };
17
- .content_type(guess_mime_type(path).as_ref())
22
+ HttpResponse::Ok().content_type(guess_mime_type(path).as_ref()).body(body)
18
- .body(Body::from_slice(content.as_ref())),
23
+ }
19
24
  None => HttpResponse::NotFound().body("404 Not Found"),
20
25
  }
21
26
  }
examples/rocket.rs CHANGED
@@ -26,11 +26,17 @@ fn index<'r>() -> response::Result<'r> {
26
26
  #[get("/dist/<file..>")]
27
27
  fn dist<'r>(file: PathBuf) -> response::Result<'r> {
28
28
  let filename = file.display().to_string();
29
- let ext = file.as_path().extension().and_then(OsStr::to_str).expect("Could not get file extension");
30
- let content_type = ContentType::from_extension(ext).expect("Could not get file content type");
31
- Asset::get(&filename.clone()).map_or_else(
29
+ Asset::get(&filename).map_or_else(
32
30
  || Err(Status::NotFound),
31
+ |d| {
32
+ let ext = file
33
+ .as_path()
34
+ .extension()
35
+ .and_then(OsStr::to_str)
36
+ .ok_or(Status::new(400, "Could not get file extension"))?;
37
+ let content_type = ContentType::from_extension(ext).ok_or(Status::new(400, "Could not get file content type"))?;
33
- |d| response::Response::build().header(content_type).sized_body(Cursor::new(d)).ok(),
38
+ response::Response::build().header(content_type).sized_body(Cursor::new(d)).ok()
39
+ },
34
40
  )
35
41
  }
36
42
 
impl/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rust-embed-impl"
3
- version = "4.1.0"
3
+ version = "4.2.0"
4
4
  description = "Rust Custom Derive Macro which loads files into the rust binary at compile time during release and loads the file from the fs during dev"
5
5
  readme = "readme.md"
6
6
  documentation = "https://docs.rs/rust-embed"
impl/src/lib.rs CHANGED
@@ -15,9 +15,9 @@ mod utils;
15
15
 
16
16
  #[cfg(all(debug_assertions, not(feature = "debug-embed")))]
17
17
  fn generate_assets(ident: &syn::Ident, folder_path: String) -> quote::Tokens {
18
- quote!{
18
+ quote! {
19
19
  impl #ident {
20
- pub fn get(file_path: &str) -> Option<impl AsRef<[u8]>> {
20
+ pub fn get(file_path: &str) -> Option<std::borrow::Cow<'static, [u8]>> {
21
21
  use std::fs::File;
22
22
  use std::io::Read;
23
23
  use std::path::Path;
@@ -31,17 +31,17 @@ fn generate_assets(ident: &syn::Ident, folder_path: String) -> quote::Tokens {
31
31
  };
32
32
  let mut data: Vec<u8> = Vec::new();
33
33
  match file.read_to_end(&mut data) {
34
- Ok(_) => Some(data),
34
+ Ok(_) => Some(std::borrow::Cow::from(data)),
35
35
  Err(_e) => {
36
36
  return None
37
37
  }
38
38
  }
39
39
  }
40
40
 
41
- pub fn iter() -> impl Iterator<Item = impl AsRef<str>> {
41
+ pub fn iter() -> impl Iterator<Item = std::borrow::Cow<'static, str>> {
42
42
  use std::path::Path;
43
43
  use rust_embed::utils::get_files;
44
- get_files(String::from(#folder_path)).map(|e| e.rel_path)
44
+ get_files(String::from(#folder_path)).map(|e| std::borrow::Cow::from(e.rel_path))
45
45
  }
46
46
  }
47
47
  }
@@ -55,26 +55,29 @@ fn generate_assets(ident: &syn::Ident, folder_path: String) -> quote::Tokens {
55
55
  let mut list_values = Vec::<String>::new();
56
56
 
57
57
  for FileEntry { rel_path, full_canonical_path } in get_files(folder_path) {
58
- match_values.push(quote!{
58
+ match_values.push(quote! {
59
+ #rel_path => {
59
- #rel_path => Some(&include_bytes!(#full_canonical_path)[..]),
60
+ let bytes = &include_bytes!(#full_canonical_path)[..];
61
+ Some(std::borrow::Cow::from(bytes))
62
+ },
60
63
  });
61
64
  list_values.push(rel_path);
62
65
  }
63
66
 
64
67
  let array_len = list_values.len();
65
68
 
66
- quote!{
69
+ quote! {
67
70
  impl #ident {
68
- pub fn get(file_path: &str) -> Option<impl AsRef<[u8]>> {
71
+ pub fn get(file_path: &str) -> Option<std::borrow::Cow<'static, [u8]>> {
69
72
  match file_path {
70
73
  #(#match_values)*
71
74
  _ => None,
72
75
  }
73
76
  }
74
77
 
75
- pub fn iter() -> impl Iterator<Item = impl AsRef<str>> {
78
+ pub fn iter() -> impl Iterator<Item = std::borrow::Cow<'static, str>> {
76
79
  static items: [&str; #array_len] = [#(#list_values),*];
77
- items.iter()
80
+ items.iter().map(|x| std::borrow::Cow::from(*x))
78
81
  }
79
82
  }
80
83
  }
readme.md CHANGED
@@ -13,7 +13,7 @@ You can use this to embed your css, js and images into a single executable which
13
13
 
14
14
  ```toml
15
15
  [dependencies]
16
- rust-embed="4.1.0"
16
+ rust-embed="4.2.0"
17
17
  ```
18
18
 
19
19
  ## Documentation
@@ -36,11 +36,11 @@ The macro will generate the following code:
36
36
 
37
37
  ```rust
38
38
  impl Asset {
39
- pub fn get(file_path: &str) -> Option<impl AsRef<[u8]>> {
39
+ pub fn get(file_path: &str) -> Option<Cow<'static, [u8]>> {
40
40
  ...
41
41
  }
42
42
 
43
- pub fn iter() -> impl Iterator<Item = impl AsRef<str>> {
43
+ pub fn iter() -> impl Iterator<Item = Cow<'static, str>> {
44
44
  ...
45
45
  }
46
46
  }
@@ -50,9 +50,9 @@ impl Asset {
50
50
 
51
51
  Given a relative path from the assets folder returns the bytes if found.
52
52
 
53
- If the feature `debug-embed` is enabled or the binary compiled in release mode the bytes have been embeded in the binary and a `&'static [u8]` is returned.
53
+ If the feature `debug-embed` is enabled or the binary compiled in release mode the bytes have been embeded in the binary and a `Cow::Borrowed(&'static [u8])` is returned.
54
54
 
55
- Otherwise the bytes are read from the file system on each call and a `Vec<u8>` is returned.
55
+ Otherwise the bytes are read from the file system on each call and a `Cow::Owned(Vec<u8>)` is returned.
56
56
 
57
57
 
58
58
  ### `iter()`