use ggen_core::ontology_pack::OntologySchema;
use ggen_utils::error::{Error, Result};
use std::path::PathBuf;
#[derive(Debug, Clone)]
pub struct ExtractInput {
pub ontology_file: PathBuf,
pub namespace: Option<String>,
pub output_path: Option<PathBuf>,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct ExtractOutput {
pub schema: OntologySchema,
pub output_file: Option<PathBuf>,
pub stats: ExtractionStats,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct ExtractionStats {
pub classes_found: usize,
pub properties_found: usize,
pub relationships_found: usize,
pub extraction_time_ms: u64,
}
pub async fn execute_extract(input: &ExtractInput) -> Result<ExtractOutput> {
let start_time = std::time::Instant::now();
if !input.ontology_file.exists() {
return Err(Error::new(&format!(
"Ontology file not found: {}",
input.ontology_file.display()
)));
}
let _file_content = tokio::fs::read_to_string(&input.ontology_file).await?;
let namespace = input.namespace.as_deref().unwrap_or("http://example.org#");
let schema = OntologySchema {
namespace: namespace.to_string(),
classes: vec![],
properties: vec![],
relationships: vec![],
prefixes: Default::default(),
};
let output_file = if let Some(output_path) = &input.output_path {
let json = serde_json::to_string_pretty(&schema)?;
tokio::fs::write(output_path, json).await?;
Some(output_path.clone())
} else {
None
};
let elapsed = start_time.elapsed();
let stats = ExtractionStats {
classes_found: schema.classes.len(),
properties_found: schema.properties.len(),
relationships_found: schema.relationships.len(),
extraction_time_ms: elapsed.as_millis() as u64,
};
Ok(ExtractOutput {
schema,
output_file,
stats,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_extract_missing_file() {
let input = ExtractInput {
ontology_file: PathBuf::from("/nonexistent/ontology.ttl"),
namespace: None,
output_path: None,
};
let result = execute_extract(&input).await;
assert!(result.is_err());
}
}