-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rewrite from proc-macro to build.rs (#15)
* Implemented build.rs flow, for single directory * Improve logging, require environment variable * Updated README * Add force-embed feature, support multiple directories (WIP) * Macro and/or build script * Always use OUT_DIR * Fix windows paths --------- Co-authored-by: cikzh <[email protected]>
- Loading branch information
1 parent
8b913b0
commit 1023a64
Showing
22 changed files
with
510 additions
and
297 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,4 @@ | ||
.vscode/ | ||
target/ | ||
/Cargo.lock | ||
Cargo.lock | ||
|
||
|
||
# Added by cargo | ||
# | ||
# already existing elements were commented out | ||
|
||
/target | ||
#/Cargo.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "memory-serve-test" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
memory-serve = { path = "../memory-serve" } | ||
axum = "0.7" | ||
tokio = { version = "1.0", features = ["full"] } | ||
tracing-subscriber = "0.3" | ||
tracing = "0.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[package] | ||
name = "memory-serve-core" | ||
description = "Shared code for memory-serve and memory-serve-macros" | ||
version.workspace = true | ||
edition.workspace = true | ||
license.workspace = true | ||
repository.workspace = true | ||
publish.workspace = true | ||
|
||
[dependencies] | ||
sha256 = "1.4" | ||
brotli = "7.0" | ||
mime_guess = "2.0" | ||
walkdir = "2" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../README.md |
15 changes: 7 additions & 8 deletions
15
memory-serve-macros/src/asset.rs → memory-serve-core/src/asset.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use std::path::{Path, PathBuf}; | ||
|
||
use crate::{asset::Asset, list::list_assets}; | ||
|
||
/// Generate code with metadata and contents for the assets | ||
pub fn assets_to_code(asset_dir: &str, path: &Path, embed: bool, log: fn(&str)) -> String { | ||
let out_dir: String = std::env::var("OUT_DIR").expect("OUT_DIR environment variable not set."); | ||
let out_dir = PathBuf::from(&out_dir); | ||
|
||
log(&format!("Loading static assets from {asset_dir}")); | ||
|
||
if embed { | ||
log("Embedding assets into binary"); | ||
} else { | ||
log("Not embedding assets into binary, assets will load dynamically"); | ||
} | ||
|
||
let assets = list_assets(path, embed, log); | ||
|
||
// using a string is faster than using quote ;) | ||
let mut code = "&[".to_string(); | ||
|
||
for asset in assets { | ||
let Asset { | ||
route, | ||
path, | ||
etag, | ||
content_type, | ||
compressed_bytes, | ||
} = asset; | ||
|
||
let bytes = if !embed { | ||
"None".to_string() | ||
} else if let Some(compressed_bytes) = &compressed_bytes { | ||
let file_name = path.file_name().expect("Unable to get file name."); | ||
let file_path = Path::new(&out_dir).join(file_name); | ||
std::fs::write(&file_path, compressed_bytes).expect("Unable to write file to out dir."); | ||
|
||
format!("Some(include_bytes!(r\"{}\"))", file_path.to_string_lossy()) | ||
} else { | ||
format!("Some(include_bytes!(r\"{}\"))", path.to_string_lossy()) | ||
}; | ||
|
||
let is_compressed = compressed_bytes.is_some(); | ||
|
||
code.push_str(&format!( | ||
" | ||
memory_serve::Asset {{ | ||
route: r\"{route}\", | ||
path: r{path:?}, | ||
content_type: \"{content_type}\", | ||
etag: \"{etag}\", | ||
bytes: {bytes}, | ||
is_compressed: {is_compressed}, | ||
}}," | ||
)); | ||
} | ||
|
||
code.push(']'); | ||
|
||
code | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
mod asset; | ||
mod code; | ||
mod list; | ||
mod util; | ||
|
||
pub use asset::Asset; | ||
pub use code::assets_to_code; | ||
|
||
/// File mime types that can possibly be compressed | ||
pub const COMPRESS_TYPES: &[&str] = &[ | ||
"text/html", | ||
"text/css", | ||
"application/json", | ||
"text/javascript", | ||
"application/javascript", | ||
"application/xml", | ||
"text/xml", | ||
"image/svg+xml", | ||
"application/wasm", | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
use std::path::Path; | ||
|
||
use walkdir::WalkDir; | ||
|
||
use crate::{ | ||
asset::Asset, | ||
util::{compress_brotli, path_to_content_type, path_to_route}, | ||
COMPRESS_TYPES, | ||
}; | ||
|
||
/// List all assets in the given directory (recursively) and return a list of assets with metadata | ||
pub fn list_assets(base_path: &Path, embed: bool, log: fn(&str)) -> Vec<Asset> { | ||
let mut assets: Vec<Asset> = WalkDir::new(base_path) | ||
.into_iter() | ||
.filter_map(|entry| entry.ok()) | ||
.filter_map(|entry| { | ||
let path = entry.path().to_owned(); | ||
let route = path_to_route(base_path, entry.path()); | ||
|
||
let Ok(metadata) = entry.metadata() else { | ||
log(&format!( | ||
"skipping file {route}, could not get file metadata" | ||
)); | ||
return None; | ||
}; | ||
|
||
// skip directories | ||
if !metadata.is_file() { | ||
return None; | ||
}; | ||
|
||
// skip empty | ||
if metadata.len() == 0 { | ||
log(&format!("skipping file {route}: file empty")); | ||
return None; | ||
} | ||
|
||
let Some(content_type) = path_to_content_type(entry.path()) else { | ||
log(&format!( | ||
"skipping file {route}, could not determine file extension" | ||
)); | ||
return None; | ||
}; | ||
|
||
// do not load assets into the binary in debug / development mode | ||
if !embed { | ||
log(&format!("including {route} (dynamically)")); | ||
|
||
return Some(Asset { | ||
route, | ||
path: path.to_owned(), | ||
content_type, | ||
etag: Default::default(), | ||
compressed_bytes: None, | ||
}); | ||
} | ||
|
||
let Ok(bytes) = std::fs::read(entry.path()) else { | ||
log(&format!("skipping file {route}: file is not readable")); | ||
return None; | ||
}; | ||
|
||
let etag: String = sha256::digest(&bytes); | ||
let original_size = bytes.len(); | ||
let is_compress_type = COMPRESS_TYPES.contains(&content_type.as_str()); | ||
let brotli_bytes = if is_compress_type { | ||
compress_brotli(&bytes) | ||
} else { | ||
None | ||
}; | ||
|
||
let mut asset = Asset { | ||
route: route.clone(), | ||
path: path.to_owned(), | ||
content_type, | ||
etag, | ||
compressed_bytes: None, | ||
}; | ||
|
||
if is_compress_type { | ||
match brotli_bytes { | ||
Some(brotli_bytes) if brotli_bytes.len() >= original_size => { | ||
log(&format!( | ||
"including {route} {original_size} bytes (compression unnecessary)" | ||
)); | ||
} | ||
Some(brotli_bytes) => { | ||
log(&format!( | ||
"including {route} {original_size} -> {} bytes (compressed)", | ||
brotli_bytes.len() | ||
)); | ||
|
||
asset.compressed_bytes = Some(brotli_bytes); | ||
} | ||
None => { | ||
log(&format!( | ||
"including {route} {original_size} bytes (compression failed)" | ||
)); | ||
} | ||
} | ||
} else { | ||
log(&format!("including {route} {original_size} bytes")); | ||
} | ||
|
||
Some(asset) | ||
}) | ||
.collect(); | ||
|
||
assets.sort(); | ||
|
||
assets | ||
} |
Oops, something went wrong.