use std::sync::Arc;
use anyhow::Result;
use async_trait::async_trait;
use log::debug;
use log::error;
use tokio_util::sync::CancellationToken;
use crate::build_project::build_project_result::BuildProjectResult;
use crate::build_project::build_project_result_holder::BuildProjectResultHolder;
use crate::cmd::service::Service;
use crate::holder::Holder as _;
use crate::search_index::SearchIndex;
use crate::search_index_reader_holder::SearchIndexReaderHolder;
pub struct SearchIndexBuilder {
pub build_project_result_holder: BuildProjectResultHolder,
pub ctrlc_notifier: CancellationToken,
pub search_index_reader_holder: SearchIndexReaderHolder,
}
impl SearchIndexBuilder {
async fn do_build_search_index(&self) {
let BuildProjectResult {
content_document_sources,
..
} = match self.build_project_result_holder.get().await {
Some(build_project_result) => build_project_result,
None => {
debug!("Build project results not ready yet. Skipping build");
return;
}
};
match SearchIndex::create_in_memory(content_document_sources).index() {
Err(err) => {
error!("Unable to index markdown document sources: {err:#?}");
}
Ok(search_index_reader) => {
self.search_index_reader_holder
.set(Some(Arc::new(search_index_reader)))
.await;
}
}
}
}
#[async_trait]
impl Service for SearchIndexBuilder {
async fn run(&self) -> Result<()> {
loop {
self.do_build_search_index().await;
tokio::select! {
_ = self.build_project_result_holder.update_notifier.notified() => continue,
_ = self.ctrlc_notifier.cancelled() => break,
}
}
Ok(())
}
}