use std::error::Error;
use erased_serde::Serialize;
use sqlx::SqlitePool;
pub struct StaticPage {
pub path: String,
pub content: String,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct SearchDoc {
pub id: String,
pub title: String,
pub body_preview: String,
#[serde(rename = "type")]
pub doc_type: String,
pub url: String,
pub published_at: Option<String>,
}
pub struct ExtBuildOutput {
pub ext_id: String,
pub pages: Vec<StaticPage>,
pub data: Box<dyn erased_serde::Serialize + Send>,
pub search_docs: Vec<SearchDoc>,
}
pub struct BuildOutput {
pub pages: Vec<StaticPage>,
pub search_docs: Vec<SearchDoc>,
pub extensions_data: Vec<(String, Box<dyn erased_serde::Serialize + Send>)>,
}
pub trait BuildExt: Send + Sync {
fn ext_id(&self) -> &'static str;
fn build_pages(
&self,
db: &SqlitePool,
rt: &tokio::runtime::Handle,
) -> Result<Vec<StaticPage>, Box<dyn Error + Send + Sync>>;
fn build_data(
&self,
db: &SqlitePool,
rt: &tokio::runtime::Handle,
) -> Result<Box<dyn Serialize + Send>, Box<dyn Error + Send + Sync>>;
fn build_search_docs(
&self,
db: &SqlitePool,
rt: &tokio::runtime::Handle,
) -> Result<Vec<SearchDoc>, Box<dyn Error + Send + Sync>>;
}
impl BuildOutput {
pub fn merge(results: impl IntoIterator<Item = ExtBuildOutput>) -> Self {
let mut pages = Vec::new();
let mut search_docs = Vec::new();
let mut extensions_data = Vec::new();
for r in results {
pages.extend(r.pages);
search_docs.extend(r.search_docs);
extensions_data.push((r.ext_id, r.data));
}
BuildOutput {
pages,
search_docs,
extensions_data,
}
}
}