v6/src/main.rs
2025-01-01 23:31:50 -05:00

88 lines
2.5 KiB
Rust

#![feature(let_chains)]
mod generator;
use clap::{Command, arg, command};
use debounced::debounced;
use futures::FutureExt;
use generator::{FileWatcher, content_base_path};
use log::info;
use std::cell::RefCell;
use std::rc::Rc;
use std::time::Duration;
use tokio::pin;
use tokio_stream::StreamExt;
use tokio_stream::wrappers::UnboundedReceiverStream;
#[tokio::main]
async fn main() {
env_logger::init();
let matches = command!()
.subcommand_required(true)
.arg_required_else_help(true)
.subcommand(
Command::new("gen")
.arg(arg!(--watch "Watch the site directory and regenerate on changes")),
)
.subcommand(
Command::new("serve")
.arg(arg!(--watch "Watch the site directory and regenerate on changes")),
)
.get_matches();
if cfg!(debug_assertions) {
info!("Running in dev mode");
} else {
info!("Running in release mode");
}
match matches.subcommand() {
Some(("gen", matches)) => {
let watcher = Rc::new(RefCell::new(FileWatcher::new()));
let mut graph = generator::generate(Rc::clone(&watcher))
.await
.expect("generating");
if matches.contains_id("watch") {
let (tx, rx) = tokio::sync::mpsc::unbounded_channel::<()>();
watcher.borrow_mut().watch(content_base_path(), move || {
tx.send(()).expect("sending regenerate signal");
});
let mut debounced =
debounced(UnboundedReceiverStream::new(rx), Duration::from_millis(100));
let watch = FileWatcher::start(watcher).fuse();
let regenerate = async move {
while let Some(_) = debounced.next().await {
info!("Regenerating");
graph.evaluate_async().await;
}
}
.fuse();
pin!(regenerate, watch);
loop {
futures::select! {
watcher_res = watch => {
watcher_res.expect("watching files");
}
_ = regenerate => {
info!("regenerate channel closed");
}
}
}
}
}
Some(("serve", _matches)) => {
todo!()
}
_ => unreachable!(),
}
}