102 lines
2.5 KiB
Rust
102 lines
2.5 KiB
Rust
pub mod mdbook;
|
|
|
|
use async_trait::async_trait;
|
|
use thiserror::Error;
|
|
|
|
use crate::document::Document;
|
|
use crate::domains::common::{DomainId, DomainModel, ModelId};
|
|
use crate::domains::GenericDocument;
|
|
use crate::registry::{Registry, RegistryError};
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum GeneratorError {
|
|
#[error("{0}")]
|
|
Engine(#[from] anyhow::Error),
|
|
#[error("{0}")]
|
|
Registry(#[from] RegistryError),
|
|
}
|
|
|
|
pub struct Generator<E, R> {
|
|
engine: E,
|
|
registry: R,
|
|
}
|
|
|
|
impl<E, R> Generator<E, R>
|
|
where
|
|
E: Engine,
|
|
R: Registry,
|
|
{
|
|
pub fn new(engine: E, registry: R) -> Self {
|
|
Self { engine, registry }
|
|
}
|
|
|
|
pub async fn generate(mut self) -> Result<(), GeneratorError> {
|
|
self.engine.start(&self.registry).await?;
|
|
macro_rules! push_documents {
|
|
($($kind:ident),+) => {
|
|
$(
|
|
for (id, doc) in self.get_documents().await? {
|
|
self.engine
|
|
.push_document(id.model_id, GenericDocument::$kind(doc), &self.registry)
|
|
.await?;
|
|
}
|
|
)*
|
|
};
|
|
}
|
|
push_documents!(
|
|
SourceIntelligence,
|
|
SourceRequirement,
|
|
SourceProvider,
|
|
ThreatTactic,
|
|
ThreatTechnique,
|
|
ThreatSoftware,
|
|
ThreatSimulation,
|
|
ObserveEvent,
|
|
ObserveDetection,
|
|
ObserveProvider,
|
|
ObserveConfiguration,
|
|
ReactStage,
|
|
ReactAction,
|
|
ReactPlaybook,
|
|
MitigateStrategy,
|
|
MitigatePlatform,
|
|
MitigateConfiguration
|
|
);
|
|
self.engine.finish(&self.registry).await
|
|
}
|
|
|
|
async fn get_documents<M>(&self) -> Result<Vec<(DomainId, Document<M>)>, GeneratorError>
|
|
where
|
|
M: DomainModel,
|
|
{
|
|
self.registry
|
|
.get_documents()
|
|
.await
|
|
.map(|mut docs| {
|
|
docs.sort_by_key(|(id, _)| *id);
|
|
docs
|
|
})
|
|
.map_err(GeneratorError::Registry)
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
pub trait Engine {
|
|
async fn start<R>(&mut self, registry: &R) -> Result<(), GeneratorError>
|
|
where
|
|
R: Registry;
|
|
|
|
async fn push_document<R>(
|
|
&mut self,
|
|
id: ModelId,
|
|
doc: GenericDocument,
|
|
registry: &R,
|
|
) -> Result<(), GeneratorError>
|
|
where
|
|
R: Registry;
|
|
|
|
async fn finish<R>(&mut self, registry: &R) -> Result<(), GeneratorError>
|
|
where
|
|
R: Registry;
|
|
}
|