Compare commits
2 Commits
1065bd1956
...
06b389b28f
Author | SHA1 | Date | |
---|---|---|---|
06b389b28f
|
|||
ce49dd6e3d
|
@@ -7,6 +7,6 @@ edition = "2024"
|
|||||||
http-body-util = "0.1.3"
|
http-body-util = "0.1.3"
|
||||||
hyper = { version = "1.6.0", features = ["full"] }
|
hyper = { version = "1.6.0", features = ["full"] }
|
||||||
hyper-util = { version = "0.1.11", features = ["full"] }
|
hyper-util = { version = "0.1.11", features = ["full"] }
|
||||||
serde = "1.0.219"
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
tokio = { version = "1.44.2", features = ["full"] }
|
tokio = { version = "1.44.2", features = ["full"] }
|
||||||
toml = "0.8.22"
|
toml = "0.8.22"
|
||||||
|
31
theseus-server/src/config.rs
Normal file
31
theseus-server/src/config.rs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
use std::net::SocketAddr;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
macro_rules! def_config {
|
||||||
|
($(config $config_id: ident
|
||||||
|
{ $([$namespace: ident $struct_name: ident]$($var_id: ident = $var_type: ty),*)*$(,)? })*
|
||||||
|
) => {
|
||||||
|
$(
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct $config_id {
|
||||||
|
$(pub $namespace: $struct_name),*
|
||||||
|
}
|
||||||
|
|
||||||
|
$(
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct $struct_name { $(pub $var_id: $var_type),* }
|
||||||
|
)*
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def_config! {
|
||||||
|
|
||||||
|
config Config {
|
||||||
|
|
||||||
|
[server Server]
|
||||||
|
bind_to = SocketAddr, // where to bind the server tcp socket in format: "<host>:<port>"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,16 +1,41 @@
|
|||||||
|
use std::sync::{atomic::AtomicU32, Arc};
|
||||||
use http_body_util::{combinators::BoxBody, BodyExt, Full};
|
use http_body_util::{combinators::BoxBody, BodyExt, Full};
|
||||||
use hyper::{body::{Bytes, Incoming}, Error, Request, Response};
|
use hyper::{
|
||||||
|
body::{Bytes, Incoming}, server::conn::http1, service::service_fn, Error, Request, Response
|
||||||
|
};
|
||||||
|
use hyper_util::rt::TokioIo;
|
||||||
|
use tokio::net::TcpListener;
|
||||||
|
|
||||||
mod args;
|
mod args;
|
||||||
|
mod config;
|
||||||
|
|
||||||
async fn router(
|
async fn router(
|
||||||
_: Request<Incoming>,
|
_: Request<Incoming>,
|
||||||
|
_: Arc<SharedState>,
|
||||||
) -> Result<Response<BoxBody<Bytes, Error>>, Error> {
|
) -> Result<Response<BoxBody<Bytes, Error>>, Error> {
|
||||||
Ok(Response::new(Full::new("test".into()).map_err(|n| match n {}).boxed()))
|
Ok(Response::new(Full::new("test".into()).map_err(|n| match n {}).boxed()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_config(path: &str) -> Result<config::Config, &'static str> {
|
||||||
|
let Ok(file_contents) = std::fs::read_to_string(path) else {
|
||||||
|
return Err("could not read the config file");
|
||||||
|
};
|
||||||
|
toml::from_str(&file_contents).map_err(|_| "invalid config file structure or fields")
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SharedState {
|
||||||
|
counter: AtomicU32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SharedState {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { counter: 0.into() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
// load config
|
||||||
let args = match args::Args::try_from(&mut std::env::args()) {
|
let args = match args::Args::try_from(&mut std::env::args()) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -18,5 +43,36 @@ async fn main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
println!("{}", args.config_path());
|
let config = match load_config(args.config_path()) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("{}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// shared state
|
||||||
|
let state = Arc::new(SharedState::default());
|
||||||
|
|
||||||
|
// server
|
||||||
|
let Ok(listener) = TcpListener::bind(config.server.bind_to).await else {
|
||||||
|
eprintln!("unable to bind to: {:?}", config.server.bind_to);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let Ok((stream, _)) = listener.accept().await else {
|
||||||
|
eprintln!("unable to accept new connections");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let io = TokioIo::new(stream);
|
||||||
|
let state_clone = state.clone();
|
||||||
|
tokio::task::spawn(async move {
|
||||||
|
if let Err(_) = http1::Builder::new().serve_connection(io, service_fn(move |req| {
|
||||||
|
router(req, state_clone.clone())
|
||||||
|
})).await {
|
||||||
|
println!("closed connection");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user