Use cargo features for serve
This commit is contained in:
parent
d5d10a4818
commit
bc5c64afd1
18
Cargo.toml
18
Cargo.toml
@ -12,6 +12,10 @@ edition = "2024"
|
|||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# 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]
|
[build-dependencies]
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
@ -33,12 +37,12 @@ grass_compiler = { version = "0.13.4", features = [
|
|||||||
"custom-builtin-fns",
|
"custom-builtin-fns",
|
||||||
], git = "https://git.shadowfacts.net/shadowfacts/grass.git", branch = "custom-global-variables" }
|
], git = "https://git.shadowfacts.net/shadowfacts/grass.git", branch = "custom-global-variables" }
|
||||||
html5ever = "0.27.0"
|
html5ever = "0.27.0"
|
||||||
http = "1.2.0"
|
http = { version = "1.2.0", optional = true }
|
||||||
http-body = "1.0.1"
|
http-body = { version = "1.0.1", optional = true }
|
||||||
http-body-util = "0.1.2"
|
http-body-util = { version = "0.1.2", optional = true }
|
||||||
hyper = { version = "1.5.2", features = ["server", "http1"] }
|
hyper = { version = "1.5.2", features = ["server", "http1"], optional = true }
|
||||||
hyper-tungstenite = "0.17.0"
|
hyper-tungstenite = { version = "0.17.0", optional = true }
|
||||||
hyper-util = { version = "0.1.10", features = ["tokio", "service"] }
|
hyper-util = { version = "0.1.10", features = ["tokio", "service"], optional = true }
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
markup5ever_rcdom = "0.3.0"
|
markup5ever_rcdom = "0.3.0"
|
||||||
notify = "7.0.0"
|
notify = "7.0.0"
|
||||||
@ -55,7 +59,7 @@ tokio = { version = "1.42.0", features = ["full"] }
|
|||||||
tokio-stream = "0.1.17"
|
tokio-stream = "0.1.17"
|
||||||
toml = "0.8.19"
|
toml = "0.8.19"
|
||||||
tower = { version = "0.5.2", features = ["steer", "util"] }
|
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-bash = "0.23.3"
|
||||||
tree-sitter-c = "0.23.4"
|
tree-sitter-c = "0.23.4"
|
||||||
tree-sitter-css = "0.23.2"
|
tree-sitter-css = "0.23.2"
|
||||||
|
@ -14,7 +14,7 @@ use tower_http::{
|
|||||||
set_status::SetStatus,
|
set_status::SetStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::CloneableReceiver;
|
use crate::serve::CloneableReceiver;
|
||||||
|
|
||||||
pub async fn handle(
|
pub async fn handle(
|
||||||
mut request: Request<hyper::body::Incoming>,
|
mut request: Request<hyper::body::Incoming>,
|
||||||
|
53
src/main.rs
53
src/main.rs
@ -1,24 +1,21 @@
|
|||||||
mod generator;
|
mod generator;
|
||||||
|
#[cfg(feature = "serve")]
|
||||||
mod live_reload;
|
mod live_reload;
|
||||||
|
#[cfg(feature = "serve")]
|
||||||
|
mod serve;
|
||||||
|
|
||||||
use clap::{Arg, ArgAction, ArgMatches, Command, command};
|
use clap::{Arg, ArgAction, ArgMatches, Command, command};
|
||||||
use compute_graph::AsyncGraph;
|
use compute_graph::AsyncGraph;
|
||||||
use debounced::debounced;
|
use debounced::debounced;
|
||||||
use futures::join;
|
use futures::join;
|
||||||
use generator::{FileWatcher, content_base_path};
|
use generator::{FileWatcher, content_base_path};
|
||||||
use hyper::server::conn::http1;
|
use log::info;
|
||||||
use hyper_util::{rt::TokioIo, service::TowerToHyperService};
|
|
||||||
use log::{error, info};
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::net::SocketAddr;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::net::TcpListener;
|
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
use tokio_stream::StreamExt;
|
use tokio_stream::StreamExt;
|
||||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||||
use tower::service_fn;
|
|
||||||
use tower_http::services::{ServeDir, ServeFile};
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
@ -66,46 +63,10 @@ async fn main() {
|
|||||||
join!(serve_future, watch_future);
|
join!(serve_future, watch_future);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CloneableReceiver<T>(pub broadcast::Receiver<T>);
|
#[allow(unused)]
|
||||||
impl<T: Clone> Clone for CloneableReceiver<T> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self(self.0.resubscribe())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn serve(matches: &ArgMatches, regen_complete_rx: broadcast::Receiver<()>) {
|
async fn serve(matches: &ArgMatches, regen_complete_rx: broadcast::Receiver<()>) {
|
||||||
if let Some(("serve", _)) = matches.subcommand() {
|
#[cfg(feature = "serve")]
|
||||||
let serve_dir = ServeDir::new("out").not_found_service(ServeFile::new("out/404.html"));
|
serve::serve(&matches, regen_complete_rx).await
|
||||||
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:?}");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn watch(
|
async fn watch(
|
||||||
|
52
src/serve.rs
Normal file
52
src/serve.rs
Normal file
@ -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<T>(pub broadcast::Receiver<T>);
|
||||||
|
impl<T: Clone> Clone for CloneableReceiver<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self(self.0.resubscribe())
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user