Skip to main content

ontocore_refactor/
model.rs

1use serde::{Deserialize, Serialize};
2use std::path::PathBuf;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
5#[serde(rename_all = "snake_case")]
6pub enum UsageKind {
7    EntityDeclaration,
8    AxiomSubject,
9    AxiomObject,
10    AnnotationSubject,
11    AnnotationObject,
12    Import,
13    TextReference,
14    SwrlReference,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct Usage {
19    pub iri: String,
20    pub referenced_iri: String,
21    pub file: PathBuf,
22    pub line: Option<u64>,
23    pub column: Option<u64>,
24    pub start_byte: Option<u64>,
25    pub end_byte: Option<u64>,
26    pub kind: UsageKind,
27    pub context: String,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct Hunk {
32    pub start_byte: u64,
33    pub end_byte: u64,
34    pub old_text: String,
35    pub new_text: String,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct FileChange {
40    pub path: PathBuf,
41    pub preview_text: String,
42    pub original_text: String,
43    #[serde(default, skip_serializing_if = "Vec::is_empty")]
44    pub hunks: Vec<Hunk>,
45}
46
47#[derive(Debug, Clone, Default, Serialize, Deserialize)]
48pub struct RefactorPlan {
49    pub changes: Vec<FileChange>,
50    #[serde(default, skip_serializing_if = "Vec::is_empty")]
51    pub warnings: Vec<String>,
52    /// Distinct entity IRIs touched by this plan (best-effort).
53    #[serde(default)]
54    pub affected_entity_count: usize,
55    /// Approximate axiom/hunk impact (sum of hunks, or 1 per changed file when hunks empty).
56    #[serde(default)]
57    pub affected_axiom_count: usize,
58}
59
60impl RefactorPlan {
61    /// Populate impact metrics from file changes and explicitly named entity IRIs.
62    pub fn with_metrics(mut self, entity_iris: impl IntoIterator<Item = impl AsRef<str>>) -> Self {
63        let mut entities: std::collections::BTreeSet<String> =
64            entity_iris.into_iter().map(|s| s.as_ref().to_string()).collect();
65        entities.retain(|iri| !iri.is_empty());
66        self.affected_entity_count = entities.len();
67        self.affected_axiom_count =
68            self.changes.iter().map(|c| if c.hunks.is_empty() { 1 } else { c.hunks.len() }).sum();
69        self
70    }
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize)]
74#[serde(tag = "kind", rename_all = "snake_case")]
75pub enum RefactorRequest {
76    RenameIri {
77        from_iri: String,
78        to_iri: String,
79    },
80    MergeEntities {
81        keep_iri: String,
82        merge_iri: String,
83    },
84    ReplaceEntity {
85        from_iri: String,
86        to_iri: String,
87    },
88    MigrateNamespace {
89        from_base: String,
90        to_base: String,
91    },
92    MoveEntity {
93        entity_iri: String,
94        target_file: PathBuf,
95    },
96    ExtractModule {
97        entity_iris: Vec<String>,
98        output_file: PathBuf,
99        #[serde(default)]
100        leave_stub: bool,
101        /// When true, expand `entity_iris` under the bottom-locality heuristic before extract.
102        #[serde(default)]
103        locality: bool,
104    },
105    /// Move selected Turtle subject statements for an entity to another file.
106    /// `statement_indexes` are 0-based indexes into `all_entity_statement_ranges`
107    /// (excluding the primary type declaration when `exclude_primary` is true).
108    MoveAxioms {
109        entity_iri: String,
110        target_file: PathBuf,
111        #[serde(default)]
112        statement_indexes: Vec<usize>,
113        #[serde(default = "default_true")]
114        exclude_primary: bool,
115    },
116    /// Merge one or more source ontology Turtle files into a target file.
117    MergeOntologies {
118        source_paths: Vec<PathBuf>,
119        target_file: PathBuf,
120    },
121    /// Inline imported Turtle axioms into a root ontology and remove `owl:imports`.
122    FlattenImports {
123        ontology_file: PathBuf,
124    },
125    /// Remove unused `owl:imports` lines (heuristic: no imported entities referenced).
126    CleanupImports {
127        ontology_file: PathBuf,
128    },
129}
130
131fn default_true() -> bool {
132    true
133}