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


34dabb93 Peter

7 years ago
Merge pull request #47 from vemoo/cow-opt
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()`