use ggen_core::ontology_pack::OntologySchema;
use ggen_utils::error::Result;
use std::path::PathBuf;
#[derive(Debug, Clone)]
pub struct ComposeInput {
pub pack_ids: Vec<String>,
pub merge_strategy: MergeStrategy,
pub language: String,
pub output_dir: PathBuf,
}
#[derive(Debug, Clone, serde::Serialize)]
pub enum MergeStrategy {
Union,
Intersection,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct ComposeOutput {
pub schema: OntologySchema,
pub files_generated: Vec<PathBuf>,
pub stats: CompositionStats,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct CompositionStats {
pub ontologies_composed: usize,
pub total_classes: usize,
pub total_properties: usize,
pub conflicts_resolved: usize,
}
pub async fn execute_compose(input: &ComposeInput) -> Result<ComposeOutput> {
let mut schemas = Vec::new();
for pack_id in &input.pack_ids {
schemas.push(OntologySchema {
namespace: format!("https://{}", pack_id),
classes: vec![],
properties: vec![],
relationships: vec![],
prefixes: Default::default(),
});
}
let merged = match input.merge_strategy {
MergeStrategy::Union => merge_union(schemas),
MergeStrategy::Intersection => merge_intersection(schemas),
}?;
tokio::fs::create_dir_all(&input.output_dir).await?;
let stats = CompositionStats {
ontologies_composed: input.pack_ids.len(),
total_classes: merged.classes.len(),
total_properties: merged.properties.len(),
conflicts_resolved: 0,
};
Ok(ComposeOutput {
schema: merged,
files_generated: vec![],
stats,
})
}
fn merge_union(schemas: Vec<OntologySchema>) -> Result<OntologySchema> {
let mut result = OntologySchema {
namespace: "composed".to_string(),
classes: vec![],
properties: vec![],
relationships: vec![],
prefixes: Default::default(),
};
for schema in schemas {
result.classes.extend(schema.classes);
result.properties.extend(schema.properties);
result.relationships.extend(schema.relationships);
result.prefixes.extend(schema.prefixes);
}
Ok(result)
}
fn merge_intersection(schemas: Vec<OntologySchema>) -> Result<OntologySchema> {
merge_union(schemas)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_merge_union() {
let schema1 = OntologySchema {
namespace: "schema1".to_string(),
classes: vec![],
properties: vec![],
relationships: vec![],
prefixes: Default::default(),
};
let schema2 = OntologySchema {
namespace: "schema2".to_string(),
classes: vec![],
properties: vec![],
relationships: vec![],
prefixes: Default::default(),
};
let result = merge_union(vec![schema1, schema2]).unwrap();
assert_eq!(result.namespace, "composed");
}
}