Skip to main content

snomed_classify/
skipped.rs

1//! Constructs `classify` recognizes but doesn't model, per
2//! `spec/13-classification.md`'s "Scope" section. Every occurrence is
3//! reported, never silently dropped without a trace.
4
5use std::fmt;
6
7use snomed_core::sctid::SctId;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum SkippedConstruct {
11    /// A `ReflexiveObjectProperty` axiom — reflexivity isn't modeled.
12    ReflexiveProperty(SctId),
13    /// A `SubDataPropertyOf` axiom — data (concrete-value) property
14    /// hierarchy isn't modeled.
15    DataProperty(SctId),
16    /// A `DataHasValue` conjunct on `attribute`, dropped from whatever
17    /// intersection or existential filler it appeared in.
18    ConcreteValue { attribute: SctId },
19    /// A `SubObjectPropertyOf` whose sub-property is an
20    /// `ObjectPropertyChain` with no operands, naming the super-property
21    /// it would have implied. `snomed-owl`'s parser rejects this shape;
22    /// only a hand-built [`snomed_owl::Axiom`] can produce it.
23    EmptyRoleChain(SctId),
24    /// A stated axiom shape `necessary_normal_form` couldn't turn into a
25    /// `(type, value)` attribute pair — e.g. a role group or ungrouped
26    /// existential whose filler isn't a plain concept (spec/14). `concept`
27    /// is the named subject whose stated profile the shape appeared in.
28    UnmodeledAttributeShape { concept: SctId },
29}
30
31impl fmt::Display for SkippedConstruct {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        match self {
34            SkippedConstruct::ReflexiveProperty(id) => {
35                write!(f, "ReflexiveObjectProperty(:{id}) is not modeled")
36            }
37            SkippedConstruct::DataProperty(id) => {
38                write!(f, "SubDataPropertyOf involving :{id} is not modeled")
39            }
40            SkippedConstruct::ConcreteValue { attribute } => {
41                write!(
42                    f,
43                    "DataHasValue on attribute :{attribute} was dropped (concrete values aren't classified)"
44                )
45            }
46            SkippedConstruct::EmptyRoleChain(target) => {
47                write!(
48                    f,
49                    "an empty ObjectPropertyChain under :{target} implies nothing and was dropped"
50                )
51            }
52            SkippedConstruct::UnmodeledAttributeShape { concept } => {
53                write!(
54                    f,
55                    "a stated attribute of :{concept} has an unmodeled shape (not a plain concept filler) and was dropped from its necessary normal form"
56                )
57            }
58        }
59    }
60}