use std::path::Path;
use std::time::Instant;
use tokio::sync::{Notify, RwLock, broadcast};
use crate::Error;
use crate::config::Config;
use crate::generated::FaviconSet;
use crate::render::{Mode, RenderedSite, Theme};
#[doc(hidden)]
pub struct AppState {
pub(crate) site: RwLock<RenderedSite>,
pub(crate) favicon: Option<FaviconSet>,
pub reload_tx: broadcast::Sender<()>,
pub(crate) shutdown: Notify,
}
impl AppState {
pub(super) fn new(rendered: RenderedSite, favicon: Option<FaviconSet>) -> Self {
let (reload_tx, _) = broadcast::channel(16);
Self {
site: RwLock::new(rendered),
favicon,
reload_tx,
shutdown: Notify::new(),
}
}
pub(crate) async fn rebuild(&self, config_path: &Path) -> Result<(), Error> {
let config = Config::from_path(config_path)?;
let start = Instant::now();
let theme = Theme::load(&config)?;
let rendered =
RenderedSite::build_with_favicon(&config, &theme, Mode::Serve, self.favicon.clone())?;
tracing::info!("rebuild complete in {}ms", start.elapsed().as_millis());
*self.site.write().await = rendered;
let _ = self.reload_tx.send(());
Ok(())
}
}