diff --git a/Makefile b/Makefile
index 2be793a..ccad206 100644
--- a/Makefile
+++ b/Makefile
@@ -5,10 +5,16 @@ build: \
dst/release/theseus-server
.PHONY: run
-run: dst/dev.toml
+run: dst/dev.toml $(TARGETS_CLIENT)
cargo run --package theseus-server -- dst/dev.toml
-dst/release/theseus-server: $(SRCS_RUST_THESEUS_SERVER)
- cargo build --package theseus-server --release
+.PHONY: clean
+clean: client_clean
+ rm -rf dst
include config/make.mk
+include client/make.mk
+
+dst/release/theseus-server: $(SRCS_RUST_THESEUS_SERVER) $(TARGETS_CLIENT)
+ cargo build --package theseus-server --release
+ touch $@
diff --git a/client/index.html b/client/index.html
new file mode 100644
index 0000000..db6ced0
--- /dev/null
+++ b/client/index.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+ Ask Stallman
+
+
+
+
+
+
+
+
+
We kindly ask you to consider this before sending:
+
+ -
+ Please write your question in English. Dr Stallman will be reading it
+ unedited during the discussion block.
+
+ - Keep it kind. We are all here to learn something.
+ -
+ Don't spam. We try to keep algorithmic moderation as permissive as possible.
+ So we ask you to moderate yourself.
+
+
+
+
+
+
diff --git a/client/make.mk b/client/make.mk
index e69de29..131deea 100644
--- a/client/make.mk
+++ b/client/make.mk
@@ -0,0 +1,31 @@
+TARGETS_CLIENT_PAGES := index.html not_found.html
+TARGETS_CLIENT_SCRIPTS := script.js
+TARGETS_CLIENT_STYLES := style.css
+TARGETS_CLIENT := $(TARGETS_CLIENT_PAGES:%=dst/%) \
+ $(TARGETS_CLIENT_SCRIPTS:%=dst/%) \
+ $(TARGETS_CLIENT_STYLES:%=dst/%)
+
+.PHONY: client_clean
+client_clean:
+ rm -rf client/node_modules
+
+client/node_modules:
+ cd client && bun install
+
+dst/%.html: client/%.html client/node_modules
+ @mkdir -p $(@D)
+ cat $< | bun run --cwd client html-minifier \
+ --collapse-inline-tag-whitespace \
+ --collapse-boolean-attributes \
+ --collapse-whitespace \
+ --remove-attribute-quotes \
+ --remove-comments \
+ --remove-redundant-attributes > $@
+
+dst/%.css: client/%.scss client/node_modules
+ @mkdir -p $(@D)
+ bun run --cwd client sass $(notdir $<) --style compressed > $@
+
+dst/%.js: client/%.ts client/node_modules
+ @mkdir -p $(@D)
+ bun build $< --minify --outfile $@
diff --git a/client/not_found.html b/client/not_found.html
new file mode 100644
index 0000000..ab830ee
--- /dev/null
+++ b/client/not_found.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+ Not Found | Ask Stallman
+
+
+
+
+
+
Not Found
+
This page was not found. Please check the URL.
+
+
+
+
diff --git a/client/script.ts b/client/script.ts
new file mode 100644
index 0000000..e69de29
diff --git a/client/style.scss b/client/style.scss
new file mode 100644
index 0000000..e69de29
diff --git a/lib/search_and_replace/Cargo.toml b/lib/search_and_replace/Cargo.toml
index 3125d2c..81a95ea 100644
--- a/lib/search_and_replace/Cargo.toml
+++ b/lib/search_and_replace/Cargo.toml
@@ -3,7 +3,4 @@ name = "search_and_replace"
version = "0.1.0"
edition = "2021"
-[profile.release]
-strip = true
-
[dependencies]
diff --git a/theseus-server/src/main.rs b/theseus-server/src/main.rs
index 012f906..c943fce 100644
--- a/theseus-server/src/main.rs
+++ b/theseus-server/src/main.rs
@@ -1,7 +1,8 @@
use std::sync::{atomic::AtomicU32, Arc};
use http_body_util::{combinators::BoxBody, BodyExt, Full};
use hyper::{
- body::{Bytes, Incoming}, server::conn::http1, service::service_fn, Error, Request, Response
+ body::{Bytes, Incoming},
+ server::conn::http1, service::service_fn, Error, Method, Request, Response
};
use hyper_util::rt::TokioIo;
use tokio::net::TcpListener;
@@ -10,11 +11,36 @@ mod logger;
mod args;
mod config;
+macro_rules! response {
+ ($status: ident $body: expr) => {{
+ let mut res = Response::new(Full::new(Bytes::from($body)).map_err(|n| match n {}).boxed());
+ *res.status_mut() = hyper::StatusCode::$status;
+ res
+ }};
+
+ ($status: ident $body: expr, $($hkey: ident : $hval: literal),*$(,)?) => {{
+ let mut res = Response::new(Full::new(Bytes::from($body)).map_err(|n| match n {}).boxed());
+ *res.status_mut() = hyper::StatusCode::$status;
+ $(res.headers_mut()
+ .append(hyper::header::$hkey, hyper::header::HeaderValue::from_static($hval));)*
+ res
+ }};
+}
+
async fn router(
- _: Request,
+ req: Request,
_: Arc,
) -> Result>, Error> {
- Ok(Response::new(Full::new("test".into()).map_err(|n| match n {}).boxed()))
+ match (req.method(), req.uri().path()) {
+ (&Method::GET, "/") => Ok(response!(
+ OK include_str!("../../dst/index.html"),
+ CONTENT_TYPE: "text/html",
+ )),
+ _ => Ok(response!(
+ NOT_FOUND include_str!("../../dst/not_found.html"),
+ CONTENT_TYPE: "text/html",
+ )),
+ }
}
fn load_config(path: &str) -> Result {