diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ba0d520..7460a3b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,6 @@ on: env: CARGO_TERM_COLOR: always - ASSET_DIR: ./static jobs: format: @@ -57,6 +56,7 @@ jobs: prefix-key: cargo shared-key: test - run: cargo test --all-features --all-targets + working-directory: ./memory-serve test-release: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 7e93dc3..c0e3a51 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,4 @@ .vscode/ target/ -/Cargo.lock +Cargo.lock - -# Added by cargo -# -# already existing elements were commented out - -/target -#/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index 24a91c4..8fd62ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ exclude = ["example"] resolver = "2" [workspace.package] -version = "1.0.0" +version = "1.0.0-beta.0" edition = "2021" license = "Apache-2.0 OR MIT" repository = "https://github.com/tweedegolf/memory-serve" diff --git a/README.md b/README.md index 8311600..b2d1f5c 100644 --- a/README.md +++ b/README.md @@ -33,11 +33,18 @@ memory-serve is designed to work with [axum](https://github.com/tokio-rs/axum) ## Usage -Provide a relative or absolute path to the directory containing your static assets -using the `ASSET_PATH` environment variable. The path will be used in a -build script, that creates a data structure intended to -be consumed by [`MemoryServe::new`]. Calling [`MemoryServe::into_router()`] on -the resulting instance produces a axum +There are two mechanisms to include assets at compile time. + +1. Specify the path using a enviroment variable `ASSET_PATH` and call: `MemoryServe::from_env()` (best-practice) +2. Call the `load_assets!` macro, and pass this to the constructor: `MemoryServe::new(load_assets!("/foo/bar"))` + +The environment variable is handled by a build script and instructs cargo to re-evaluate when an asset in the directory changes. +The output of the macro might be cached between build. + +Both options try to be smart in resolving absolute and relative paths. + +When an instance of `MemoryServe` is created, we can bind these to your axum instance. +Calling [`MemoryServe::into_router()`] on the `MemoryServe` instance produces an axum [`Router`](https://docs.rs/axum/latest/axum/routing/struct.Router.html) that can either be merged in another `Router` or used directly in a server by calling [`Router::into_make_service()`](https://docs.rs/axum/latest/axum/routing/struct.Router.html#method.into_make_service). @@ -46,7 +53,17 @@ calling [`Router::into_make_service()`](https://docs.rs/axum/latest/axum/routing Multiple directories can be included using different environment variables, all prefixed by `ASSET_PATH_`. For example: if you specify `ASSET_PATH_FOO` and `ASSET_PATH_BAR` the memory serve instances can be loaded -using `MemoryServe::from_name("FOO")` and `MemoryServe::from_name("BAR")` respectively. +using `MemoryServe::from_env_name("FOO")` and `MemoryServe::from_env_name("BAR")` respectively. + +### Features + +Use the `force-embed` feature flag to always include assets in the binary - also in debug builds. + +### Environment variables + +Use `MEMORY_SERVE_ROOT` to specify a root directory for relative paths provided to the `load_assets!` macro (or th `ASSET_PATH` variable). + +Uee `MEMORY_SERVE_QUIET=1` to not print log messages at compile time. ## Example diff --git a/example/Cargo.lock b/example/Cargo.lock deleted file mode 100644 index a73d848..0000000 --- a/example/Cargo.lock +++ /dev/null @@ -1,1051 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "async-trait" -version = "0.1.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "axum" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" -dependencies = [ - "async-trait", - "axum-core", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-util", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sync_wrapper 1.0.1", - "tokio", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "axum-core" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "mime", - "pin-project-lite", - "rustversion", - "sync_wrapper 1.0.1", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "brotli" -version = "7.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bytes" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "flate2" -version = "1.0.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "pin-utils", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "http" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" -dependencies = [ - "bytes", - "futures-util", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", -] - -[[package]] -name = "hyper-util" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" -dependencies = [ - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "pin-project-lite", - "tokio", - "tower-service", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.161" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "memory-serve" -version = "1.0.0" -dependencies = [ - "axum", - "brotli", - "flate2", - "memory-serve-core", - "memory-serve-macros", - "sha256", - "tracing", -] - -[[package]] -name = "memory-serve-core" -version = "1.0.0" -dependencies = [ - "brotli", - "mime_guess", - "sha256", - "walkdir", -] - -[[package]] -name = "memory-serve-macros" -version = "1.0.0" -dependencies = [ - "memory-serve-core", - "proc-macro2", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "memory-serve-test" -version = "0.0.0" -dependencies = [ - "axum", - "memory-serve", - "tokio", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi", - "libc", - "wasi", - "windows-sys 0.52.0", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "object" -version = "0.36.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project-lite" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "proc-macro2" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustversion" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "serde" -version = "1.0.214" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.214" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.132" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_path_to_error" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" -dependencies = [ - "itoa", - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha256" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0" -dependencies = [ - "async-trait", - "bytes", - "hex", - "sha2", - "tokio", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "syn" -version = "2.0.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "sync_wrapper" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "tokio" -version = "1.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-macros" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tower" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper 0.1.2", - "tokio", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "nu-ansi-term", - "sharded-slab", - "smallvec", - "thread_local", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "unicase" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/example/Cargo.toml b/example/Cargo.toml index 63eda0e..d4b39bf 100644 --- a/example/Cargo.toml +++ b/example/Cargo.toml @@ -3,7 +3,7 @@ name = "memory-serve-test" edition = "2021" [dependencies] -memory-serve = { path = "../memory-serve"} +memory-serve = { path = "../memory-serve" } axum = "0.7" tokio = { version = "1.0", features = ["full"] } tracing-subscriber = "0.3" diff --git a/example/src/main.rs b/example/src/main.rs index af402ef..fd22589 100644 --- a/example/src/main.rs +++ b/example/src/main.rs @@ -1,5 +1,5 @@ use axum::{response::Html, routing::get, Router}; -use memory_serve::MemoryServe; +use memory_serve::{MemoryServe, load_assets}; use std::net::SocketAddr; use tracing::{info, Level}; @@ -9,7 +9,7 @@ async fn main() { .with_max_level(Level::TRACE) .init(); - let memory_router = MemoryServe::from_env() + let memory_router = MemoryServe::new(load_assets!("../static")) .index_file(Some("/index.html")) .into_router(); diff --git a/memory-serve-core/src/code.rs b/memory-serve-core/src/code.rs index 702a7be..e6bd195 100644 --- a/memory-serve-core/src/code.rs +++ b/memory-serve-core/src/code.rs @@ -2,8 +2,22 @@ use std::path::Path; use crate::{asset::Asset, list::list_assets}; -pub fn assets_to_code(asset_dir: &str, path: &Path, out_dir: &Path, embed: bool, log: fn(&str)) -> String { +/// Generate code with metadata and contents for the assets +pub fn assets_to_code( + asset_dir: &str, + path: &Path, + out_dir: &Path, + embed: bool, + log: fn(&str), +) -> String { 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 ;) @@ -48,4 +62,4 @@ pub fn assets_to_code(asset_dir: &str, path: &Path, out_dir: &Path, embed: bool, code.push(']'); code -} \ No newline at end of file +} diff --git a/memory-serve-core/src/lib.rs b/memory-serve-core/src/lib.rs index 6b8b45c..7f62187 100644 --- a/memory-serve-core/src/lib.rs +++ b/memory-serve-core/src/lib.rs @@ -1,12 +1,12 @@ - mod asset; -mod list; 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", @@ -17,4 +17,4 @@ pub const COMPRESS_TYPES: &[&str] = &[ "text/xml", "image/svg+xml", "application/wasm", -]; \ No newline at end of file +]; diff --git a/memory-serve-core/src/list.rs b/memory-serve-core/src/list.rs index e952a39..cdea2aa 100644 --- a/memory-serve-core/src/list.rs +++ b/memory-serve-core/src/list.rs @@ -2,8 +2,13 @@ use std::path::Path; use walkdir::WalkDir; -use crate::{asset::Asset, util::{compress_brotli, path_to_content_type, path_to_route}, COMPRESS_TYPES}; +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 { let mut assets: Vec = WalkDir::new(base_path) .into_iter() @@ -13,7 +18,9 @@ pub fn list_assets(base_path: &Path, embed: bool, log: fn(&str)) -> Vec { 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")); + log(&format!( + "skipping file {route}, could not get file metadata" + )); return None; }; @@ -29,7 +36,9 @@ pub fn list_assets(base_path: &Path, embed: bool, log: fn(&str)) -> Vec { } let Some(content_type) = path_to_content_type(entry.path()) else { - log(&format!("skipping file {route}, could not determine file extension")); + log(&format!( + "skipping file {route}, could not determine file extension" + )); return None; }; @@ -71,7 +80,9 @@ pub fn list_assets(base_path: &Path, embed: bool, log: fn(&str)) -> Vec { 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)")); + log(&format!( + "including {route} {original_size} bytes (compression unnecessary)" + )); } Some(brotli_bytes) => { log(&format!( @@ -82,7 +93,9 @@ pub fn list_assets(base_path: &Path, embed: bool, log: fn(&str)) -> Vec { asset.compressed_bytes = Some(brotli_bytes); } None => { - log(&format!("including {route} {original_size} bytes (compression failed)")); + log(&format!( + "including {route} {original_size} bytes (compression failed)" + )); } } } else { @@ -96,4 +109,4 @@ pub fn list_assets(base_path: &Path, embed: bool, log: fn(&str)) -> Vec { assets.sort(); assets -} \ No newline at end of file +} diff --git a/memory-serve-core/src/util.rs b/memory-serve-core/src/util.rs index 9bb8dfd..e56df2b 100644 --- a/memory-serve-core/src/util.rs +++ b/memory-serve-core/src/util.rs @@ -2,6 +2,7 @@ use std::{io::Write, path::Path}; use mime_guess::mime; +/// Convert a path to a (HTTP) path / route pub(crate) fn path_to_route(base: &Path, path: &Path) -> String { let relative_path = path .strip_prefix(base) @@ -19,6 +20,7 @@ pub(crate) fn path_to_route(base: &Path, path: &Path) -> String { format!("/{route}") } +/// Determine the mime type of a file pub(crate) fn path_to_content_type(path: &Path) -> Option { let ext = path.extension()?; @@ -30,6 +32,7 @@ pub(crate) fn path_to_content_type(path: &Path) -> Option { ) } +/// Compress a byte slice using brotli pub(crate) fn compress_brotli(input: &[u8]) -> Option> { let mut writer = brotli::CompressorWriter::new(Vec::new(), 4096, 11, 22); writer.write_all(input).ok()?; diff --git a/memory-serve-macros/Cargo.toml b/memory-serve-macros/Cargo.toml index 0749a09..8cf529c 100644 --- a/memory-serve-macros/Cargo.toml +++ b/memory-serve-macros/Cargo.toml @@ -12,10 +12,7 @@ proc-macro = true [features] force-embed = [] -silent = [] [dependencies] memory-serve-core = { path = "../memory-serve-core" } -proc-macro2 = "1.0" -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["fmt", "ansi"], default-features = false } +proc-macro2 = "1.0" \ No newline at end of file diff --git a/memory-serve-macros/src/lib.rs b/memory-serve-macros/src/lib.rs index 2c5a49e..42f3767 100644 --- a/memory-serve-macros/src/lib.rs +++ b/memory-serve-macros/src/lib.rs @@ -1,7 +1,6 @@ +use memory_serve_core::assets_to_code; use proc_macro::TokenStream; -use tracing::warn; use std::{env, path::Path}; -use memory_serve_core::assets_to_code; #[proc_macro] pub fn load_assets(input: TokenStream) -> TokenStream { @@ -9,14 +8,10 @@ pub fn load_assets(input: TokenStream) -> TokenStream { let asset_dir = input.trim_matches('"'); let mut path = Path::new(&asset_dir).to_path_buf(); - // skip if a subscriber is already registered (for instance by rust_analyzer) - let _ = tracing_subscriber::fmt() - .without_time() - .with_target(false) - .try_init(); - - fn log (msg: &str) { - warn!("{msg}"); + fn log(msg: &str) { + if std::env::var("MEMORY_SERVE_QUIET") != Ok("1".to_string()) { + println!(" memory_serve: {msg}"); + } } if path.is_relative() { diff --git a/memory-serve/Cargo.toml b/memory-serve/Cargo.toml index bd9a32f..77ba3b0 100644 --- a/memory-serve/Cargo.toml +++ b/memory-serve/Cargo.toml @@ -1,15 +1,14 @@ [package] name = "memory-serve" -version = "1.0.0" -edition = "2021" -license = "Apache-2.0 OR MIT" -repository = "https://github.com/tweedegolf/memory-serve" -description = "Fast static file serving for axum web applications" -publish = true +description.workspace = true +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +publish.workspace = true [features] force-embed = ["memory-serve-macros/force-embed"] -silent = ["memory-serve-macros/silent"] [dependencies] memory-serve-core = { path = "../memory-serve-core" } diff --git a/memory-serve/build.rs b/memory-serve/build.rs index 2cda98e..b5b4e49 100644 --- a/memory-serve/build.rs +++ b/memory-serve/build.rs @@ -1,23 +1,29 @@ -use std::path::{Path, PathBuf}; use memory_serve_core::assets_to_code; +use std::path::{Path, PathBuf}; const ASSET_FILE: &str = "memory_serve_assets.rs"; const ENV_NAME: &str = "ASSET_DIR"; +const QUIET_ENV_NAME: &str = "MEMORY_SERVE_QUIET"; fn resolve_asset_dir(out_dir: &Path, key: &str, asset_dir: &str) -> PathBuf { let path = Path::new(&asset_dir); let path: PathBuf = if path.is_relative() { - // assume the out dit is in the target directory - let crate_root = out_dir - .parent() // memory-serve - .and_then(|p| p.parent()) // build - .and_then(|p| p.parent()) // debug/release - .and_then(|p| p.parent()) // target - .and_then(|p| p.parent()) // crate root - .expect("Unable to get crate root directory."); - - crate_root.join(path) + if let Ok(root_dir) = std::env::var("MEMORY_SERVE_ROOT") { + let root_dir = Path::new(&root_dir); + root_dir.join(path) + } else { + // assume the out dit is in the target directory + let crate_root = out_dir + .parent() // memory-serve + .and_then(|p| p.parent()) // build + .and_then(|p| p.parent()) // debug/release + .and_then(|p| p.parent()) // target + .and_then(|p| p.parent()) // crate root + .expect("Unable to get crate root directory."); + + crate_root.join(path) + } } else { path.to_path_buf() }; @@ -39,7 +45,9 @@ fn main() { let out_dir = PathBuf::from(&out_dir); fn log(msg: &str) { - println!("cargo:warning={}", msg); + if std::env::var(QUIET_ENV_NAME) != Ok("1".to_string()) { + println!("cargo:warning={}", msg); + } } // deternmine wheter to dynamically load assets or embed them in the binary @@ -64,7 +72,9 @@ fn main() { code.push(']'); + println!("cargo::rerun-if-env-changed=CARGO_FEATURE_FORCE_EMBED"); println!("cargo::rerun-if-env-changed={ENV_NAME}"); + println!("cargo::rerun-if-env-changed={QUIET_ENV_NAME}"); let target = out_dir.join(ASSET_FILE); std::fs::write(target, code).expect("Unable to write memory-serve asset file."); diff --git a/memory-serve/src/asset.rs b/memory-serve/src/asset.rs index 96acd9f..d5ba1a4 100644 --- a/memory-serve/src/asset.rs +++ b/memory-serve/src/asset.rs @@ -5,8 +5,8 @@ use axum::{ }, response::{IntoResponse, Response}, }; -use tracing::debug; use memory_serve_core::COMPRESS_TYPES; +use tracing::debug; use crate::{ util::{compress_brotli, compress_gzip, content_length, supports_encoding}, @@ -22,6 +22,7 @@ const GZIP_ENCODING: &str = "gzip"; const GZIP_HEADER: (HeaderName, HeaderValue) = (CONTENT_ENCODING, HeaderValue::from_static(GZIP_ENCODING)); +/// Represents a static asset that can be served #[derive(Debug)] pub struct Asset { pub route: &'static str, diff --git a/memory-serve/src/lib.rs b/memory-serve/src/lib.rs index 85feb92..ed69cec 100644 --- a/memory-serve/src/lib.rs +++ b/memory-serve/src/lib.rs @@ -56,6 +56,9 @@ pub struct MemoryServe { } impl MemoryServe { + /// Initiate a `MemoryServe` instance, takes the output of `load_assets!` + /// as an argument. `load_assets!` takes a directory name relative from + /// the project root. pub fn new(assets: &'static [Asset]) -> Self { Self { assets, @@ -402,7 +405,9 @@ mod tests { #[tokio::test] async fn brotli_compression() { - let memory_router = MemoryServe::new(load_assets!("../static")).enable_brotli(true).into_router(); + let memory_router = MemoryServe::new(load_assets!("../static")) + .enable_brotli(true) + .into_router(); let (code, headers) = get( memory_router.clone(), "/index.html", @@ -418,7 +423,9 @@ mod tests { assert_eq!(length.parse::().unwrap(), 178); // check disable compression - let memory_router = MemoryServe::new(load_assets!("../static")).enable_brotli(false).into_router(); + let memory_router = MemoryServe::new(load_assets!("../static")) + .enable_brotli(false) + .into_router(); let (code, headers) = get( memory_router.clone(), "/index.html", @@ -434,7 +441,9 @@ mod tests { #[tokio::test] async fn gzip_compression() { - let memory_router = MemoryServe::new(load_assets!("../static")).enable_gzip(true).into_router(); + let memory_router = MemoryServe::new(load_assets!("../static")) + .enable_gzip(true) + .into_router(); let (code, headers) = get( memory_router.clone(), "/index.html", @@ -451,7 +460,9 @@ mod tests { assert_eq!(length.parse::().unwrap(), 274); // check disable compression - let memory_router = MemoryServe::new(load_assets!("../static")).enable_gzip(false).into_router(); + let memory_router = MemoryServe::new(load_assets!("../static")) + .enable_gzip(false) + .into_router(); let (code, headers) = get( memory_router.clone(), "/index.html", @@ -467,7 +478,9 @@ mod tests { #[tokio::test] async fn index_file() { - let memory_router = MemoryServe::new(load_assets!("../static")).index_file(None).into_router(); + let memory_router = MemoryServe::new(load_assets!("../static")) + .index_file(None) + .into_router(); let (code, _) = get(memory_router.clone(), "/", "accept", "*").await; assert_eq!(code, 404); @@ -501,7 +514,9 @@ mod tests { #[tokio::test] async fn clean_url() { - let memory_router = MemoryServe::new(load_assets!("../static")).enable_clean_url(true).into_router(); + let memory_router = MemoryServe::new(load_assets!("../static")) + .enable_clean_url(true) + .into_router(); let (code, _) = get(memory_router.clone(), "/about.html", "accept", "*").await; assert_eq!(code, 404); diff --git a/memory-serve/src/util.rs b/memory-serve/src/util.rs index 05d755e..32b6296 100644 --- a/memory-serve/src/util.rs +++ b/memory-serve/src/util.rs @@ -5,6 +5,7 @@ use axum::http::{ HeaderMap, HeaderName, HeaderValue, }; +/// Decompress a byte slice using brotli pub(crate) fn decompress_brotli(input: &[u8]) -> Option> { let mut writer = brotli::DecompressorWriter::new(Vec::new(), 1024); writer.write_all(input).ok()?; @@ -12,6 +13,7 @@ pub(crate) fn decompress_brotli(input: &[u8]) -> Option> { writer.into_inner().ok() } +/// Compress a byte slice using gzip pub(crate) fn compress_brotli(input: &[u8]) -> Option> { let mut writer = brotli::CompressorWriter::new(Vec::new(), 4096, 11, 22); writer.write_all(input).ok()?; @@ -19,6 +21,7 @@ pub(crate) fn compress_brotli(input: &[u8]) -> Option> { Some(writer.into_inner()) } +/// Compress a byte slice using gzip pub(crate) fn compress_gzip(input: &[u8]) -> Option> { let mut writer = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::best()); writer.write_all(input).ok()?; @@ -26,6 +29,7 @@ pub(crate) fn compress_gzip(input: &[u8]) -> Option> { writer.finish().ok() } +/// Check if the client supports the given encoding pub(crate) fn supports_encoding(headers: &HeaderMap, encoding: &str) -> bool { let Some(header_value) = headers .get(ACCEPT_ENCODING)