wip
This commit is contained in:
56
Cargo.lock
generated
56
Cargo.lock
generated
@@ -541,6 +541,15 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.8"
|
||||
@@ -622,6 +631,7 @@ name = "templateServe"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"macro_rules_attribute",
|
||||
@@ -630,6 +640,7 @@ dependencies = [
|
||||
"smol",
|
||||
"smol-hyper",
|
||||
"smol-macros",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -655,6 +666,45 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.9.11+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_parser",
|
||||
"toml_writer",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.7.5+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.0.6+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44"
|
||||
dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_writer"
|
||||
version = "1.0.6+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.44"
|
||||
@@ -694,3 +744,9 @@ checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
|
||||
|
||||
@@ -7,6 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.100"
|
||||
bytes = "1.11.0"
|
||||
http-body-util = "0.1.3"
|
||||
hyper = { version = "1.8.1", features = ["http1", "http2", "server"] }
|
||||
macro_rules_attribute = "0.2.2"
|
||||
@@ -15,3 +16,4 @@ serde = { version = "1.0.228", features = ["derive"] }
|
||||
smol = "2.0.2"
|
||||
smol-hyper = "0.1.1"
|
||||
smol-macros = "0.1.1"
|
||||
toml = "0.9.11"
|
||||
|
||||
44
bleh.txt
Normal file
44
bleh.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
- templete-serve
|
||||
- config.toml
|
||||
- home
|
||||
- id: "MAINHOME"
|
||||
- type: root
|
||||
- assets
|
||||
- pngs & mp4's
|
||||
- base
|
||||
- config.toml
|
||||
- id: "base"
|
||||
- title: ""
|
||||
- type: page
|
||||
- path: Empty, Not meant to be visited
|
||||
- comment: "Base page that others can extend from"
|
||||
- include: [style.css] // <- FEATURE FOR LATER
|
||||
- extras
|
||||
- index.html
|
||||
- home
|
||||
- config.toml
|
||||
- id: "mainHome"
|
||||
- title: "home"
|
||||
- type: page
|
||||
- path: "/"
|
||||
- extras
|
||||
- web stamps
|
||||
- extra data yk
|
||||
- index.html
|
||||
- second
|
||||
- config.toml
|
||||
- id: "secondPage"
|
||||
- title: "bleh"
|
||||
- type: page
|
||||
- path: "/"
|
||||
- extras
|
||||
- web stamps
|
||||
- extra data yk
|
||||
- index.html
|
||||
- 404
|
||||
- config.toml
|
||||
- id: "404page"
|
||||
- title: "home"
|
||||
- type: page
|
||||
- path: "/404"
|
||||
- index.html
|
||||
83
src/loader.rs
Normal file
83
src/loader.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
use std::future::IntoFuture;
|
||||
|
||||
use crate::AppState;
|
||||
use anyhow::anyhow;
|
||||
use minijinja::Value;
|
||||
use serde::Deserialize;
|
||||
use smol::{
|
||||
fs::{self, DirEntry},
|
||||
stream::StreamExt,
|
||||
};
|
||||
use toml::Table;
|
||||
|
||||
pub struct Page {
|
||||
header: Header,
|
||||
content: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub enum PageType {
|
||||
// If root, the dir contains all the pages, if there are no dirs within the root, we can assume
|
||||
// its empty
|
||||
Root,
|
||||
// Contains a single html
|
||||
Page,
|
||||
// Is template
|
||||
Base,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct Header {
|
||||
id: String,
|
||||
// r#type: PageType,
|
||||
r#type: String,
|
||||
title: Option<String>,
|
||||
path: Option<String>,
|
||||
// TODO impl this later
|
||||
// extras: Table,
|
||||
}
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct Root {
|
||||
id: String,
|
||||
// r#type: PageType,
|
||||
r#type: String,
|
||||
title: Option<String>,
|
||||
path: Option<String>,
|
||||
// TODO impl this later
|
||||
// extras: Table,
|
||||
}
|
||||
|
||||
impl AppState<'_> {
|
||||
pub async fn load_from_fs(&mut self) -> anyhow::Result<()> {
|
||||
let mut dir = fs::read_dir("./template-serve").await?;
|
||||
|
||||
// Find config.toml from within dir
|
||||
let config = dir
|
||||
.find(|x| x.as_ref().unwrap().file_name().eq("config.toml"))
|
||||
.await
|
||||
.unwrap()?;
|
||||
|
||||
while let Some(Ok(entry)) = dir.next().await {
|
||||
if entry.file_type().await?.is_dir() {
|
||||
let entry_opened = fs::read_dir(entry.path()).await?;
|
||||
println!("Opened {}", entry.file_name().to_str().unwrap());
|
||||
} else {
|
||||
println!("Not parsing {}", entry.file_name().to_str().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
let config_file = fs::read(config.path()).await?;
|
||||
|
||||
let config_parsed: Root = toml::from_slice(config_file.as_slice())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// impl From<Table> for Value {
|
||||
// fn from(value: Table) -> Self {
|
||||
// Value {
|
||||
// ..Default::default()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
80
src/main.rs
80
src/main.rs
@@ -1,56 +1,78 @@
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::pin::Pin;
|
||||
use std::string;
|
||||
use std::sync::Arc;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use anyhow::Result;
|
||||
use bytes::Bytes;
|
||||
use http_body_util::Full;
|
||||
use hyper::body::Incoming;
|
||||
use hyper::service::service_fn;
|
||||
use hyper::{Request, Response, Uri};
|
||||
use hyper::{Request, Response};
|
||||
use macro_rules_attribute::apply;
|
||||
use smol::{future, io, prelude::*, Async, Executor};
|
||||
use minijinja::{context, Environment};
|
||||
use smol::{fs, io, prelude::*, Async, Executor};
|
||||
use smol_hyper::rt::{FuturesIo, SmolTimer};
|
||||
use smol_macros::main;
|
||||
|
||||
/// Serves a request and returns a response.
|
||||
async fn serve(req: Request<Incoming>) -> Result<Response<Full<&'static [u8]>>> {
|
||||
println!("Serving {}", req.uri());
|
||||
let path = req.uri().path();
|
||||
let reply = match path {
|
||||
"/" => "mreow",
|
||||
_ => "Invalid path!",
|
||||
};
|
||||
Ok(Response::new(Full::new(reply.as_bytes())))
|
||||
mod loader;
|
||||
use crate::loader::*;
|
||||
|
||||
struct AppState<'a> {
|
||||
pages: Vec<Page>,
|
||||
env: Environment<'a>,
|
||||
}
|
||||
|
||||
/// Handle a new client.
|
||||
async fn handle_client(client: Async<TcpStream>) -> Result<()> {
|
||||
// Wrap it in TLS if necessary.
|
||||
/// Serves a request and returns a response.
|
||||
async fn serve(req: Request<Incoming>, state: Arc<AppState<'_>>) -> Result<Response<Full<Bytes>>> {
|
||||
println!("Serving {}", req.uri());
|
||||
|
||||
let tmpl = state.env.get_template("hello").unwrap();
|
||||
let guh = tmpl.render(context!(name => "meowmeowmeowmeow!")).unwrap();
|
||||
let guh2 = state.env.get_template("meow").unwrap();
|
||||
let guh3 = guh2.render(context!(meow => "meow")).unwrap();
|
||||
|
||||
let path = req.uri().path();
|
||||
let reply: Bytes = match path {
|
||||
"/" => guh.into(),
|
||||
"/mreow" => guh3.into(),
|
||||
_ => "Invalid path!".into(),
|
||||
};
|
||||
Ok(Response::new(Full::new(reply)))
|
||||
}
|
||||
|
||||
async fn handle_client(client: Async<TcpStream>, state: Arc<AppState<'_>>) -> Result<()> {
|
||||
let client = SmolStream::Plain(client);
|
||||
|
||||
// Build the server.
|
||||
hyper::server::conn::http1::Builder::new()
|
||||
.timer(SmolTimer::new())
|
||||
.serve_connection(FuturesIo::new(client), service_fn(serve))
|
||||
.serve_connection(
|
||||
FuturesIo::new(client),
|
||||
service_fn(move |req| serve(req, state.clone())),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Listens for incoming connections and serves them.
|
||||
async fn listen(ex: &Arc<Executor<'static>>, listener: Async<TcpListener>) -> Result<()> {
|
||||
async fn listen(
|
||||
ex: &Arc<Executor<'static>>,
|
||||
listener: Async<TcpListener>,
|
||||
state: Arc<AppState<'static>>,
|
||||
) -> Result<()> {
|
||||
// Format the full host address.
|
||||
// println!("Listening on {}", host);
|
||||
|
||||
loop {
|
||||
// Wait for a new client.
|
||||
let (client, _) = listener.accept().await?;
|
||||
let cloned_state = state.clone();
|
||||
|
||||
// Spawn a task to handle this connection.
|
||||
ex.spawn({
|
||||
async move {
|
||||
if let Err(e) = handle_client(client).await {
|
||||
if let Err(e) = handle_client(client, cloned_state).await {
|
||||
println!("Error while handling client: {}", e);
|
||||
}
|
||||
}
|
||||
@@ -59,11 +81,25 @@ async fn listen(ex: &Arc<Executor<'static>>, listener: Async<TcpListener>) -> Re
|
||||
}
|
||||
}
|
||||
|
||||
async fn init<'a>() -> Result<AppState<'a>> {
|
||||
let mut env = Environment::new();
|
||||
let mut pages: Vec<Page> = Vec::new();
|
||||
let mut state: AppState = AppState { pages, env };
|
||||
state.load_from_fs().await?;
|
||||
|
||||
Ok(state)
|
||||
}
|
||||
|
||||
#[apply(main!)]
|
||||
async fn main(ex: &Arc<Executor<'static>>) -> Result<()> {
|
||||
// Start HTTP and HTTPS servers.
|
||||
let _ = listen(ex, Async::<TcpListener>::bind(([127, 0, 0, 1], 8000))?).await;
|
||||
print!("mroew");
|
||||
let mut state = init().await?;
|
||||
|
||||
let _ = listen(
|
||||
ex,
|
||||
Async::<TcpListener>::bind(([127, 0, 0, 1], 8000))?,
|
||||
Arc::new(state),
|
||||
)
|
||||
.await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
2
template-serve/config.toml
Normal file
2
template-serve/config.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
id = "mainhome"
|
||||
type = "Root"
|
||||
0
template-serve/home/config.toml
Normal file
0
template-serve/home/config.toml
Normal file
Reference in New Issue
Block a user