Boom we're looking so clean
This commit is contained in:
parent
96575cf40b
commit
769aba26e2
7 changed files with 105 additions and 21 deletions
21
Cargo.lock
generated
21
Cargo.lock
generated
|
@ -154,7 +154,7 @@ version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa"
|
checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck 0.4.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
|
@ -236,6 +236,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
|
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -250,6 +251,18 @@ dependencies = [
|
||||||
"strsim",
|
"strsim",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
|
||||||
|
dependencies = [
|
||||||
|
"heck 0.5.0",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_lex"
|
name = "clap_lex"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
@ -620,6 +633,12 @@ version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = { version = "0.7.5", features = ["macros", "tokio"] }
|
axum = { version = "0.7.5", features = ["macros", "tokio"] }
|
||||||
clap = "4.5.4"
|
clap = { version = "4.5.4", features = ["derive"] }
|
||||||
color-eyre = "0.6.3"
|
color-eyre = "0.6.3"
|
||||||
config = "0.14.0"
|
config = "0.14.0"
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
|
|
47
src/cli.rs
47
src/cli.rs
|
@ -1 +1,48 @@
|
||||||
|
use crate::prelude::*;
|
||||||
|
use prelude::*;
|
||||||
|
|
||||||
|
mod prelude {
|
||||||
|
pub use clap::{Args, Parser, Subcommand};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Web application for managing lyrics and live displays
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(version, about, long_about = None)]
|
||||||
|
#[command(propagate_version = true)]
|
||||||
|
pub struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
command: Commands,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
enum Commands {
|
||||||
|
/// Run the web application server
|
||||||
|
Run(Run),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Doc comment
|
||||||
|
#[derive(Args)]
|
||||||
|
struct Run {
|
||||||
|
/// Doc comment
|
||||||
|
#[arg(short, long, default_value = None)]
|
||||||
|
pub watch: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Run {
|
||||||
|
pub async fn run(&self) -> Result<()> {
|
||||||
|
let (router, _watchers) = crate::router::router(self.watch).await?;
|
||||||
|
crate::webserver::webserver(router, self.watch).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cli() -> Result<Cli> {
|
||||||
|
Ok(Cli::parse())
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cli {
|
||||||
|
pub async fn exec(self) -> Result<()> {
|
||||||
|
match self.command {
|
||||||
|
Commands::Run(args) => args.run().await,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ mod webserver;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
// load configuration?
|
|
||||||
let _setup_logging = observe::setup_logging();
|
let _setup_logging = observe::setup_logging();
|
||||||
webserver::webserver(router::router().await?).await
|
cli::cli()?.exec().await
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,40 @@
|
||||||
use crate::{prelude::*, state::State as AppState, static_files};
|
use crate::{file_watcher::FileWatcher, prelude::*, state::State as AppState, static_files};
|
||||||
use axum::{extract::State, response::Html, routing::get, Router};
|
use axum::{extract::State, response::Html, routing::get, Router};
|
||||||
use minijinja::context;
|
use minijinja::context;
|
||||||
use tower_livereload::LiveReloadLayer;
|
use tower_livereload::LiveReloadLayer;
|
||||||
|
|
||||||
pub async fn router() -> Result<Router> {
|
pub async fn router(with_watchers: bool) -> Result<(Router, Vec<Option<FileWatcher>>)> {
|
||||||
let state = AppState::try_new().await?;
|
let state = AppState::try_new().await?;
|
||||||
|
|
||||||
let lr = LiveReloadLayer::new();
|
let live_reload_layer: Option<LiveReloadLayer> = if with_watchers {
|
||||||
let _template_file_watcher = state
|
Some(LiveReloadLayer::new())
|
||||||
.clone()
|
} else {
|
||||||
.templates
|
None
|
||||||
.start_watcher(Some(lr.reloader()))
|
};
|
||||||
.await?;
|
|
||||||
let (static_file_service, _static_file_watcher) = static_files::router(Some(lr.reloader()))?;
|
|
||||||
|
|
||||||
Ok(Router::new()
|
let orl = || {
|
||||||
|
if let Some(lr) = &live_reload_layer {
|
||||||
|
Some(lr.reloader())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let template_file_watcher = state.clone().templates.start_watcher(orl()).await?;
|
||||||
|
let (static_file_service, static_file_watcher) = static_files::router(orl())?;
|
||||||
|
|
||||||
|
let mut result = Router::new()
|
||||||
.route("/", get(index))
|
.route("/", get(index))
|
||||||
.nest_service("/static", static_file_service)
|
.nest_service("/static", static_file_service)
|
||||||
.layer(lr)
|
.with_state(state.clone());
|
||||||
.with_state(state))
|
|
||||||
|
if let Some(lr) = live_reload_layer {
|
||||||
|
result = result.clone().layer(lr);
|
||||||
|
}
|
||||||
|
|
||||||
|
let watchers = vec![template_file_watcher, static_file_watcher];
|
||||||
|
|
||||||
|
Ok((result, watchers))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn index(State(state): State<AppState>) -> Result<Html<String>> {
|
async fn index(State(state): State<AppState>) -> Result<Html<String>> {
|
||||||
|
|
|
@ -4,7 +4,6 @@ use pathdiff::diff_paths;
|
||||||
use std::{path::PathBuf, sync::Arc};
|
use std::{path::PathBuf, sync::Arc};
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use tower_livereload::Reloader;
|
use tower_livereload::Reloader;
|
||||||
use tracing::{info, instrument};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Templates {
|
pub struct Templates {
|
||||||
|
@ -51,12 +50,15 @@ impl Templates {
|
||||||
Ok(watcher)
|
Ok(watcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument]
|
|
||||||
pub async fn load_env(&self) -> Result<()> {
|
pub async fn load_env(&self) -> Result<()> {
|
||||||
info!("Loading templates...");
|
info!("Loading templates...");
|
||||||
for d in walkdir::WalkDir::new(&self.dir) {
|
for d in walkdir::WalkDir::new(&self.dir) {
|
||||||
match d {
|
match d {
|
||||||
Ok(d) => {
|
Ok(d) => {
|
||||||
|
// ignore editor temporary files
|
||||||
|
if [".bck", ".tmp"].iter().any(|s| d.path().ends_with(s)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if d.file_type().is_dir() {
|
if d.file_type().is_dir() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::{prelude::*, tailwind};
|
use crate::{prelude::*, tailwind};
|
||||||
use axum::{serve, Router};
|
use axum::{serve, Router};
|
||||||
|
|
||||||
pub async fn webserver(router: Router) -> Result<()> {
|
pub async fn webserver(router: Router, with_watchers: bool) -> Result<()> {
|
||||||
// TODO: only start tailwind if in dev mode?
|
if with_watchers {
|
||||||
tokio::spawn(async move { tailwind::start_watcher() });
|
tokio::spawn(async move { tailwind::start_watcher() });
|
||||||
|
}
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||||
info!("Listening on {listener:?}");
|
info!("Listening on {listener:?}");
|
||||||
|
|
Loading…
Reference in a new issue