diff options
-rw-r--r-- | makefile | 2 | ||||
-rw-r--r-- | readme.md | 8 | ||||
-rw-r--r-- | server/src/assets.rs | 69 | ||||
-rw-r--r-- | server/src/main.rs | 5 |
4 files changed, 69 insertions, 15 deletions
@@ -20,7 +20,7 @@ kill-watch: pkill cargo || true pkill make || true install-server: client-build - cargo +nightly install --force --path server --features standalone + cargo +nightly install --force --path server install-native: cargo +nightly install --force --path client-native-gui cargo +nightly install --force --path client-native-rift @@ -37,15 +37,15 @@ make install-server # binaries will be copied to ~/.cargo/bin ``` When changing code, use `make watch` to re-build things automatically as needed. -(might require `cargo install systemfd cargo-watch`) +(requires `cargo install systemfd cargo-watch`) The client configuration file (`config/client.toml`) configures the client and requires server recompilation on change for now. The server's bind address can be controlled using the `BIND` environment -variable. In production you can also activate the `standalone` feature (enabled -when using `make install`) to embed all assets into the binary; This speeds it -up and allows the server to run from just the binary. +variable. When compilin without debug assertions (release) all assets are +embedded into the binary; This is a speedup and allows the server to run from +just the binary. If you use this project or have any suggestions, please [contact me](https://metamuffin.org/contact) diff --git a/server/src/assets.rs b/server/src/assets.rs index 6047164..d6e94a2 100644 --- a/server/src/assets.rs +++ b/server/src/assets.rs @@ -1,7 +1,5 @@ -use std::fs::read_to_string; - -use grass::StdFs; use log::error; +use std::sync::LazyLock; #[cfg(debug_assertions)] #[macro_export] @@ -55,13 +53,68 @@ macro_rules! s_asset_dir { }}; } -pub fn css_bundle() -> String { - grass::from_string( - read_to_string("../client-web/style/master.sass").unwrap(), +#[derive(Debug)] +struct GrassFs; +#[cfg(debug_assertions)] +impl GrassFs { + pub fn map(p: &std::path::Path) -> std::path::PathBuf { + std::path::PathBuf::try_from("../client-web/style") + .unwrap() + .join(p.file_name().unwrap()) + } +} +#[cfg(debug_assertions)] +impl grass::Fs for GrassFs { + fn is_dir(&self, path: &std::path::Path) -> bool { + Self::map(path).is_dir() + } + fn is_file(&self, path: &std::path::Path) -> bool { + Self::map(path).is_file() + } + fn read(&self, path: &std::path::Path) -> std::io::Result<Vec<u8>> { + std::fs::read(Self::map(path)) + } +} + +#[cfg(not(debug_assertions))] +const STYLE_DIR: include_dir::Dir = + include_dir::include_dir!("$CARGO_MANIFEST_DIR/../client-web/style"); +#[cfg(not(debug_assertions))] +impl grass::Fs for GrassFs { + fn is_dir(&self, _path: &std::path::Path) -> bool { + false + } + fn is_file(&self, path: &std::path::Path) -> bool { + STYLE_DIR.get_file(path.file_name().unwrap()).is_some() + } + fn read(&self, path: &std::path::Path) -> std::io::Result<Vec<u8>> { + Ok(STYLE_DIR + .get_file(path.file_name().unwrap()) + .ok_or(std::io::Error::new( + std::io::ErrorKind::NotFound, + "not found", + ))? + .contents() + .to_vec()) + } +} + +static CSS_BUNDLE: LazyLock<String> = LazyLock::new(css_bundle); + +pub fn css() -> String { + if cfg!(debug_assertions) { + css_bundle() + } else { + CSS_BUNDLE.clone() + } +} +fn css_bundle() -> String { + grass::from_path( + "/master.sass", &grass::Options::default() .input_syntax(grass::InputSyntax::Sass) - .load_path("../client-web/style") - .fs(&StdFs), + .load_path("/") + .fs(&GrassFs), ) .unwrap_or_else(|err| { error!("sass compile failed: {err}"); diff --git a/server/src/main.rs b/server/src/main.rs index 431d668..57ec4df 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -3,12 +3,13 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2022 metamuffin <metamuffin@disroot.org> */ +#![feature(lazy_cell)] pub mod assets; pub mod config; pub mod protocol; pub mod room; -use assets::css_bundle; +use assets::css; use config::{ClientAppearanceConfig, ClientConfig}; use hyper::{header, StatusCode}; use listenfd::ListenFd; @@ -70,7 +71,7 @@ async fn run() { warp::reply::with_header(client_config_css.clone(), "content-type", "text/css") }); let css: _ = warp::path!("style.css") - .map(move || warp::reply::with_header(css_bundle(), "content-type", "text/css")); + .map(move || warp::reply::with_header(css(), "content-type", "text/css")); let favicon: _ = warp::path!("favicon.ico").map(|| ""); let old_format_redirect: _ = warp::path!("room" / String).map(|rsecret| { reply::with_header( |