use std::path::Path;
use crate::ontology::rdf::Graph;
use crate::ontology::receipts;
pub mod apr_model;
pub mod code;
pub mod gguf;
pub mod json;
pub mod lean;
pub mod parity_receipt;
pub mod pv_contract;
pub mod release_evidence;
pub mod release_inputs;
#[derive(Debug, Clone, Default)]
pub struct Extraction {
pub graph: Graph,
pub warnings: Vec<json::Warning>,
pub entities_extracted: Vec<String>,
pub gguf: gguf::GgufStats,
pub apr_model: apr_model::AprStats,
pub receipts: Vec<receipts::Receipt>,
pub resolve: receipts::ResolveStats,
pub code: code::CodeStats,
pub lean: lean::LeanStats,
pub parity: parity_receipt::ParityStats,
pub release: Option<release_evidence::ReleaseStats>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExtractFailure {
Json(json::ExtractError),
Receipt(receipts::ReceiptError),
Release(release_inputs::ReleaseError),
}
impl std::fmt::Display for ExtractFailure {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Json(e) => write!(f, "{e}"),
Self::Receipt(e) => write!(f, "receipt {e}"),
Self::Release(e) => write!(f, "{e}"),
}
}
}
impl std::error::Error for ExtractFailure {}
pub fn all(contract_dir: &Path) -> Result<Extraction, ExtractFailure> {
all_with(contract_dir, None)
}
pub fn all_with(
contract_dir: &Path,
release: Option<&release_inputs::Subject>,
) -> Result<Extraction, ExtractFailure> {
let mut out = Extraction {
graph: pv_contract::extract(contract_dir),
..Extraction::default()
};
let root = contract_dir.parent().unwrap_or(contract_dir);
for (stem, _rel, doc) in pv_contract::documents(contract_dir) {
if !json::applies(&doc) {
continue;
}
let mut warnings =
json::extract_into(&mut out.graph, &stem, &doc, root).map_err(ExtractFailure::Json)?;
out.warnings.append(&mut warnings);
out.entities_extracted.push(stem);
}
out.gguf = gguf::extract(contract_dir, &mut out.graph);
out.apr_model = apr_model::extract(contract_dir, &mut out.graph);
out.receipts = receipts::read_all(root).map_err(ExtractFailure::Receipt)?;
out.resolve = receipts::resolve(&mut out.graph, &out.gguf.rungs, &out.receipts);
out.code = code::extract(contract_dir, &mut out.graph);
out.lean = lean::extract(contract_dir, &mut out.graph);
out.parity = parity_receipt::extract(root, &mut out.graph);
if let Some(subject) = release {
out.release = Some(
release_evidence::extract(&mut out.graph, contract_dir, subject)
.map_err(ExtractFailure::Release)?,
);
}
Ok(out)
}
#[must_use]
pub fn repo_root(contract_dir: &Path) -> std::path::PathBuf {
match contract_dir.parent() {
Some(p) if !p.as_os_str().is_empty() => p.to_path_buf(),
_ => std::path::PathBuf::from("."),
}
}