From bc5c64afd1d693c6da698280e5e07a17d650d48d Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 22 Feb 2025 11:15:30 -0500 Subject: [PATCH] Use cargo features for serve --- Cargo.toml | 18 ++++++++++------ src/live_reload.rs | 2 +- src/main.rs | 53 ++++++---------------------------------------- src/serve.rs | 52 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 54 deletions(-) create mode 100644 src/serve.rs diff --git a/Cargo.toml b/Cargo.toml index c702407..741c91f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,10 @@ edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +default = ["serve"] +serve = ["dep:http", "dep:http-body", "dep:http-body-util", "dep:hyper", "dep:hyper-tungstenite", "dep:hyper-util", "dep:tower-http"] + [build-dependencies] serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -33,12 +37,12 @@ grass_compiler = { version = "0.13.4", features = [ "custom-builtin-fns", ], git = "https://git.shadowfacts.net/shadowfacts/grass.git", branch = "custom-global-variables" } html5ever = "0.27.0" -http = "1.2.0" -http-body = "1.0.1" -http-body-util = "0.1.2" -hyper = { version = "1.5.2", features = ["server", "http1"] } -hyper-tungstenite = "0.17.0" -hyper-util = { version = "0.1.10", features = ["tokio", "service"] } +http = { version = "1.2.0", optional = true } +http-body = { version = "1.0.1", optional = true } +http-body-util = { version = "0.1.2", optional = true } +hyper = { version = "1.5.2", features = ["server", "http1"], optional = true } +hyper-tungstenite = { version = "0.17.0", optional = true } +hyper-util = { version = "0.1.10", features = ["tokio", "service"], optional = true } log = "0.4.22" markup5ever_rcdom = "0.3.0" notify = "7.0.0" @@ -55,7 +59,7 @@ tokio = { version = "1.42.0", features = ["full"] } tokio-stream = "0.1.17" toml = "0.8.19" tower = { version = "0.5.2", features = ["steer", "util"] } -tower-http = { version = "0.6.2", features = ["fs"] } +tower-http = { version = "0.6.2", features = ["fs"], optional = true } tree-sitter-bash = "0.23.3" tree-sitter-c = "0.23.4" tree-sitter-css = "0.23.2" diff --git a/src/live_reload.rs b/src/live_reload.rs index c7c27ea..7a3aa5c 100644 --- a/src/live_reload.rs +++ b/src/live_reload.rs @@ -14,7 +14,7 @@ use tower_http::{ set_status::SetStatus, }; -use crate::CloneableReceiver; +use crate::serve::CloneableReceiver; pub async fn handle( mut request: Request, diff --git a/src/main.rs b/src/main.rs index b567037..00a4583 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,24 +1,21 @@ mod generator; +#[cfg(feature = "serve")] mod live_reload; +#[cfg(feature = "serve")] +mod serve; use clap::{Arg, ArgAction, ArgMatches, Command, command}; use compute_graph::AsyncGraph; use debounced::debounced; use futures::join; use generator::{FileWatcher, content_base_path}; -use hyper::server::conn::http1; -use hyper_util::{rt::TokioIo, service::TowerToHyperService}; -use log::{error, info}; +use log::info; use std::cell::RefCell; -use std::net::SocketAddr; use std::rc::Rc; use std::time::Duration; -use tokio::net::TcpListener; use tokio::sync::broadcast; use tokio_stream::StreamExt; use tokio_stream::wrappers::UnboundedReceiverStream; -use tower::service_fn; -use tower_http::services::{ServeDir, ServeFile}; #[tokio::main] async fn main() { @@ -66,46 +63,10 @@ async fn main() { join!(serve_future, watch_future); } -struct CloneableReceiver(pub broadcast::Receiver); -impl Clone for CloneableReceiver { - fn clone(&self) -> Self { - Self(self.0.resubscribe()) - } -} - +#[allow(unused)] async fn serve(matches: &ArgMatches, regen_complete_rx: broadcast::Receiver<()>) { - if let Some(("serve", _)) = matches.subcommand() { - let serve_dir = ServeDir::new("out").not_found_service(ServeFile::new("out/404.html")); - let receiver = CloneableReceiver(regen_complete_rx); - let service = - service_fn(move |req| live_reload::handle(req, serve_dir.clone(), receiver.clone())); - - let addr = SocketAddr::from(( - if cfg!(debug_assertions) { - [0, 0, 0, 0] - } else { - [127, 0, 0, 1] - }, - 8084, - )); - info!("Listening on {addr}"); - - let listener = TcpListener::bind(addr).await.expect("binding to tcp port"); - loop { - let (tcp, _) = listener.accept().await.expect("accepting connection"); - let io = TokioIo::new(tcp); - let service = TowerToHyperService::new(service.clone()); - tokio::task::spawn(async move { - let result = http1::Builder::new() - .serve_connection(io, service) - .with_upgrades() - .await; - if let Err(e) = result { - error!("Error handling connection: {e:?}"); - } - }); - } - } + #[cfg(feature = "serve")] + serve::serve(&matches, regen_complete_rx).await } async fn watch( diff --git a/src/serve.rs b/src/serve.rs new file mode 100644 index 0000000..ea7deef --- /dev/null +++ b/src/serve.rs @@ -0,0 +1,52 @@ +use clap::ArgMatches; +use hyper::server::conn::http1; +use hyper_util::{rt::TokioIo, service::TowerToHyperService}; +use log::{error, info}; +use std::net::SocketAddr; +use tokio::net::TcpListener; +use tokio::sync::broadcast; +use tower::service_fn; +use tower_http::services::{ServeDir, ServeFile}; + +pub async fn serve(matches: &ArgMatches, regen_complete_rx: broadcast::Receiver<()>) { + if let Some(("serve", _)) = matches.subcommand() { + let serve_dir = ServeDir::new("out").not_found_service(ServeFile::new("out/404.html")); + let receiver = CloneableReceiver(regen_complete_rx); + let service = service_fn(move |req| { + crate::live_reload::handle(req, serve_dir.clone(), receiver.clone()) + }); + + let addr = SocketAddr::from(( + if cfg!(debug_assertions) { + [0, 0, 0, 0] + } else { + [127, 0, 0, 1] + }, + 8084, + )); + info!("Listening on {addr}"); + + let listener = TcpListener::bind(addr).await.expect("binding to tcp port"); + loop { + let (tcp, _) = listener.accept().await.expect("accepting connection"); + let io = TokioIo::new(tcp); + let service = TowerToHyperService::new(service.clone()); + tokio::task::spawn(async move { + let result = http1::Builder::new() + .serve_connection(io, service) + .with_upgrades() + .await; + if let Err(e) = result { + error!("Error handling connection: {e:?}"); + } + }); + } + } +} + +pub struct CloneableReceiver(pub broadcast::Receiver); +impl Clone for CloneableReceiver { + fn clone(&self) -> Self { + Self(self.0.resubscribe()) + } +}