Work on modularizing - things were getting messy
This commit is contained in:
parent
7b79205148
commit
1843f9fac3
11 changed files with 177 additions and 105 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -757,7 +757,9 @@ dependencies = [
|
|||
"futures",
|
||||
"minijinja",
|
||||
"notify",
|
||||
"pathdiff",
|
||||
"redact",
|
||||
"serde",
|
||||
"sled",
|
||||
"tokio",
|
||||
"tower",
|
||||
|
@ -765,6 +767,7 @@ dependencies = [
|
|||
"tower-livereload",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1232,18 +1235,18 @@ checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.200"
|
||||
version = "1.0.201"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f"
|
||||
checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.200"
|
||||
version = "1.0.201"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb"
|
||||
checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -12,7 +12,9 @@ config = "0.14.0"
|
|||
futures = "0.3.30"
|
||||
minijinja = { version = "2.0.1", features = ["loader"] }
|
||||
notify = "6.1.1"
|
||||
pathdiff = "0.2.1"
|
||||
redact = { version = "0.1.9", features = ["serde"] }
|
||||
serde = "1.0.201"
|
||||
sled = "0.34.7"
|
||||
tokio = { version = "1.37.0", features = ["full"] }
|
||||
tower = "0.4.13"
|
||||
|
@ -20,3 +22,4 @@ tower-http = { version = "0.5.2", features = ["fs"] }
|
|||
tower-livereload = "0.9.2"
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
walkdir = "2.5.0"
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
pkg-config
|
||||
inotify-tools
|
||||
tailwindcss
|
||||
nodePackages.typescript-language-server
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{% extends "page.html.jinja" %}
|
||||
{% block body %}
|
||||
<h1>Index</h1>
|
||||
<p class="important">
|
||||
Welcome to my awesome homepage.
|
||||
</p>
|
||||
{% endblock %}
|
80
src/main.rs
80
src/main.rs
|
@ -2,14 +2,11 @@ use axum::extract::State;
|
|||
use axum::response::IntoResponse;
|
||||
use axum::routing::get;
|
||||
use axum::{http::StatusCode, response::Html, serve, Router};
|
||||
use minijinja::{context, Environment};
|
||||
use minijinja::context;
|
||||
use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
|
||||
use std::process::Stdio;
|
||||
use std::sync::Arc;
|
||||
use std::{path::PathBuf, str::FromStr, sync::OnceLock};
|
||||
use tokio::io::{AsyncBufReadExt, BufReader};
|
||||
use templates::Templates;
|
||||
use tokio::sync::mpsc::channel;
|
||||
use tokio::sync::Mutex;
|
||||
use tower_http::services::ServeDir;
|
||||
use tower_livereload::{LiveReloadLayer, Reloader};
|
||||
pub use tracing::{debug, error, event, info, span, warn, Level};
|
||||
|
@ -18,19 +15,9 @@ pub use tracing::{debug, error, event, info, span, warn, Level};
|
|||
struct Berr(Box<dyn std::error::Error>);
|
||||
type Besult<T> = std::result::Result<T, Berr>;
|
||||
|
||||
mod observe {
|
||||
pub fn setup_logging() {
|
||||
color_eyre::install().expect("Failed to install color_eyre");
|
||||
|
||||
let filter = tracing_subscriber::EnvFilter::builder()
|
||||
.with_default_directive(<tracing_subscriber::filter::Directive>::from(
|
||||
tracing::level_filters::LevelFilter::TRACE,
|
||||
))
|
||||
.parse_lossy("info,lyrs=trace");
|
||||
|
||||
tracing_subscriber::fmt().with_env_filter(filter).init();
|
||||
}
|
||||
}
|
||||
mod observe;
|
||||
mod tailwind;
|
||||
mod templates;
|
||||
|
||||
fn static_file_dir() -> &'static PathBuf {
|
||||
static STATIC_FILE_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
|
@ -39,53 +26,22 @@ fn static_file_dir() -> &'static PathBuf {
|
|||
|
||||
#[derive(Clone)]
|
||||
struct AppState {
|
||||
templates: Arc<Mutex<Environment<'static>>>,
|
||||
templates: Templates,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Besult<()> {
|
||||
// load configuration?
|
||||
observe::setup_logging();
|
||||
let _setup_logging = observe::setup_logging();
|
||||
|
||||
// TODO: reload templates when they change? separate watcher?
|
||||
let templates = Templates::try_load().await?;
|
||||
let mut tt = templates.clone();
|
||||
let templates_watcher = tt.start_watcher();
|
||||
|
||||
// TODO: only start tailwind if in dev mode?
|
||||
tokio::spawn(async move {
|
||||
info!("Starting tailwind...");
|
||||
match tokio::process::Command::new("tailwindcss")
|
||||
.args(["-i", "src/style.css", "-o", "static/style.css", "--watch"])
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
{
|
||||
Ok(mut tw) => {
|
||||
info!("Tailwind spawned!");
|
||||
let mut stdout_reader = BufReader::new(tw.stdout.take().unwrap()).lines();
|
||||
tokio::spawn(async move {
|
||||
while let Ok(Some(l)) = stdout_reader.next_line().await {
|
||||
if l.trim().len() > 0 {
|
||||
event!(target: "tailwind::stdout", Level::INFO, "{l}");
|
||||
}
|
||||
}
|
||||
});
|
||||
let mut stderr_reader = BufReader::new(tw.stderr.take().unwrap()).lines();
|
||||
tokio::spawn(async move {
|
||||
while let Ok(Some(l)) = stderr_reader.next_line().await {
|
||||
if l.trim().len() > 0 {
|
||||
event!(target: "tailwind::stderr", Level::INFO, "{l}");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Err(e) => error!("Failed to spawn Tailwind: {e}"),
|
||||
}
|
||||
});
|
||||
|
||||
let templates = Arc::new(Mutex::new(Environment::new()));
|
||||
while let Some(d) = tokio::fs::read_dir("templates").await?.next_entry().await? {
|
||||
templates.clone().lock().await.add_template_owned(
|
||||
d.file_name().into_string().unwrap(),
|
||||
std::fs::read_to_string(d.path())?,
|
||||
)?;
|
||||
}
|
||||
tokio::spawn(async { tailwind::start_watcher() });
|
||||
tokio::spawn(async move { templates_watcher.await });
|
||||
|
||||
// pulling the watcher into main's scope lets it live until the program dies
|
||||
let (rl_layer, _watcher) = live_reload_layer()?;
|
||||
|
@ -105,10 +61,8 @@ async fn index(State(state): State<AppState>) -> Besult<Html<String>> {
|
|||
Ok(Html(
|
||||
state
|
||||
.templates
|
||||
.lock()
|
||||
.await
|
||||
.get_template("page.html")?
|
||||
.render(context!())?,
|
||||
.render("pages/index.html.jinja", context!())
|
||||
.await?,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -142,9 +96,7 @@ fn static_file_watcher(
|
|||
watcher.watch(static_file_dir(), RecursiveMode::Recursive)?;
|
||||
|
||||
tokio::spawn(async move {
|
||||
info!("Recieving...");
|
||||
while let Some(res) = rx.recv().await {
|
||||
info!("Recieved! {res:#?}");
|
||||
match res {
|
||||
Ok(event) => {
|
||||
info!("fs event: {event:#?}");
|
||||
|
|
11
src/observe.rs
Normal file
11
src/observe.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
pub fn setup_logging() {
|
||||
color_eyre::install().expect("Failed to install color_eyre");
|
||||
|
||||
let filter = tracing_subscriber::EnvFilter::builder()
|
||||
.with_default_directive(<tracing_subscriber::filter::Directive>::from(
|
||||
tracing::level_filters::LevelFilter::TRACE,
|
||||
))
|
||||
.parse_lossy("info,lyrs=trace");
|
||||
|
||||
tracing_subscriber::fmt().with_env_filter(filter).init();
|
||||
}
|
37
src/tailwind.rs
Normal file
37
src/tailwind.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
use std::process::Stdio;
|
||||
use tokio::{
|
||||
io::{AsyncBufReadExt, BufReader},
|
||||
process::Command,
|
||||
};
|
||||
use tracing::{error, event, info, Level};
|
||||
|
||||
pub fn start_watcher() {
|
||||
info!("Starting tailwind...");
|
||||
match Command::new("tailwindcss")
|
||||
.args(["-i", "src/style.css", "-o", "static/style.css", "--watch"])
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
{
|
||||
Ok(mut tw) => {
|
||||
info!("Tailwind spawned!");
|
||||
let mut stdout_reader = BufReader::new(tw.stdout.take().unwrap()).lines();
|
||||
tokio::spawn(async move {
|
||||
while let Ok(Some(l)) = stdout_reader.next_line().await {
|
||||
if l.trim().len() > 0 {
|
||||
event!(target: "tailwind::stdout", Level::INFO, "{l}");
|
||||
}
|
||||
}
|
||||
});
|
||||
let mut stderr_reader = BufReader::new(tw.stderr.take().unwrap()).lines();
|
||||
tokio::spawn(async move {
|
||||
while let Ok(Some(l)) = stderr_reader.next_line().await {
|
||||
if l.trim().len() > 0 {
|
||||
event!(target: "tailwind::stderr", Level::INFO, "{l}");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Err(e) => error!("Failed to spawn Tailwind: {e}"),
|
||||
}
|
||||
}
|
68
src/templates.rs
Normal file
68
src/templates.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use minijinja::Environment;
|
||||
use pathdiff::diff_paths;
|
||||
use tokio::sync::Mutex;
|
||||
use tracing::info;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Templates {
|
||||
env: Arc<Mutex<Environment<'static>>>,
|
||||
}
|
||||
|
||||
pub type Error = Box<dyn std::error::Error>;
|
||||
|
||||
impl Templates {
|
||||
pub fn empty() -> Self {
|
||||
let env = Arc::new(Mutex::new(Environment::new()));
|
||||
Self { env }
|
||||
}
|
||||
|
||||
pub async fn try_load() -> Result<Self, Error> {
|
||||
let mut result = Self::empty();
|
||||
result.load_env().await?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn start_watcher(&mut self) {
|
||||
info!("TODO: Implement template watcher");
|
||||
}
|
||||
|
||||
pub async fn load_env(&mut self) -> Result<(), Error> {
|
||||
info!("Loading templates...");
|
||||
for d in walkdir::WalkDir::new("src/templates") {
|
||||
match d {
|
||||
Ok(d) => {
|
||||
if d.file_type().is_dir() {
|
||||
continue;
|
||||
}
|
||||
let filename: String = diff_paths(d.path(), "src/templates")
|
||||
.unwrap()
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
info!("Loading template {filename:#?} ({d:#?})");
|
||||
self.env
|
||||
.clone()
|
||||
.lock()
|
||||
.await
|
||||
.add_template_owned(filename, std::fs::read_to_string(d.path())?)?;
|
||||
}
|
||||
Err(_) => todo!(),
|
||||
}
|
||||
}
|
||||
info!("Done loading templates!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn render<S: serde::ser::Serialize>(
|
||||
&self,
|
||||
template_name: &str,
|
||||
context: S,
|
||||
) -> Result<String, minijinja::Error> {
|
||||
self.env
|
||||
.lock()
|
||||
.await
|
||||
.get_template(template_name)?
|
||||
.render(context)
|
||||
}
|
||||
}
|
7
src/templates/pages/index.html.jinja
Normal file
7
src/templates/pages/index.html.jinja
Normal file
|
@ -0,0 +1,7 @@
|
|||
{% extends "page.html.jinja" %}
|
||||
{% block body %}
|
||||
<h1>Index</h1>
|
||||
<p class="important">
|
||||
Welcome to my awesome homepage!
|
||||
</p>
|
||||
{% endblock %}
|
|
@ -1,38 +1,35 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["./src/**/*.rs","./static/**/*.{html,js}"], theme: {
|
||||
content: ["./src/**/*"], theme: {
|
||||
colors: {
|
||||
|
||||
rosewater: "var(--Rosewater)",
|
||||
flamingo: "var(--Flamingo)",
|
||||
pink: "var(--Pink)",
|
||||
mauve: "var(--Mauve)",
|
||||
red: "var(--Red)",
|
||||
maroon: "var(--Maroon)",
|
||||
peach: "var(--Peach)",
|
||||
yellow: "var(--Yellow)",
|
||||
green: "var(--Green)",
|
||||
teal: "var(--Teal)",
|
||||
sky: "var(--Sky)",
|
||||
sapphire: "var(--Sapphire)",
|
||||
blue: "var(--Blue)",
|
||||
lavender: "var(--Lavender)",
|
||||
text: "var(--Text)",
|
||||
subtext1: "var(--Subtext1)",
|
||||
subtext0: "var(--Subtext0)",
|
||||
overlay2: "var(--Overlay2)",
|
||||
overlay1: "var(--Overlay1)",
|
||||
overlay0: "var(--Overlay0)",
|
||||
surface2: "var(--Surface2)",
|
||||
surface1: "var(--Surface1)",
|
||||
surface0: "var(--Surface0)",
|
||||
base: "var(--Base)",
|
||||
mantle: "var(--Mantle)",
|
||||
crust: "var(--Crust)",
|
||||
|
||||
rosewater: "var(--Rosewater)",
|
||||
flamingo: "var(--Flamingo)",
|
||||
pink: "var(--Pink)",
|
||||
mauve: "var(--Mauve)",
|
||||
red: "var(--Red)",
|
||||
maroon: "var(--Maroon)",
|
||||
peach: "var(--Peach)",
|
||||
yellow: "var(--Yellow)",
|
||||
green: "var(--Green)",
|
||||
teal: "var(--Teal)",
|
||||
sky: "var(--Sky)",
|
||||
sapphire: "var(--Sapphire)",
|
||||
blue: "var(--Blue)",
|
||||
lavender: "var(--Lavender)",
|
||||
text: "var(--Text)",
|
||||
subtext1: "var(--Subtext1)",
|
||||
subtext0: "var(--Subtext0)",
|
||||
overlay2: "var(--Overlay2)",
|
||||
overlay1: "var(--Overlay1)",
|
||||
overlay0: "var(--Overlay0)",
|
||||
surface2: "var(--Surface2)",
|
||||
surface1: "var(--Surface1)",
|
||||
surface0: "var(--Surface0)",
|
||||
base: "var(--Base)",
|
||||
mantle: "var(--Mantle)",
|
||||
crust: "var(--Crust)",
|
||||
},
|
||||
extend: {
|
||||
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
|
|
Loading…
Reference in a new issue