Skip to main content

owl_structural_model/
annotation.rs

1//! OWL annotation values.
2
3use iri_rfc3987::Iri;
4
5use crate::{BlankNodeId, OperandSet, OwlLiteral};
6
7/// An OWL annotation.
8#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
9#[serde(deny_unknown_fields)]
10pub struct Annotation<L = OwlLiteral, B = BlankNodeId> {
11    annotations: AxiomAnnotations<L, B>,
12    property: Iri<String>,
13    value: AnnotationValue<L, B>,
14}
15
16impl<L, B> Annotation<L, B> {
17    /// Create an annotation from an annotation property IRI and value.
18    #[must_use]
19    pub fn new(property: Iri<String>, value: AnnotationValue<L, B>) -> Self {
20        Self {
21            annotations: AxiomAnnotations::empty(),
22            property,
23            value,
24        }
25    }
26
27    /// Replace the annotations attached to this annotation.
28    #[must_use]
29    pub fn with_annotations(mut self, annotations: AxiomAnnotations<L, B>) -> Self {
30        self.annotations = annotations;
31        self
32    }
33    /// Return recursively nested annotations.
34    #[must_use]
35    pub fn annotations(&self) -> &AxiomAnnotations<L, B> {
36        &self.annotations
37    }
38    /// Return the annotation property IRI.
39    #[must_use]
40    pub fn property(&self) -> &Iri<String> {
41        &self.property
42    }
43
44    /// Return the annotation value.
45    #[must_use]
46    pub fn value(&self) -> &AnnotationValue<L, B> {
47        &self.value
48    }
49}
50
51/// A value that can appear in an OWL annotation.
52#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
53#[serde(deny_unknown_fields)]
54pub enum AnnotationValue<L = OwlLiteral, B = BlankNodeId> {
55    /// An IRI-valued annotation.
56    Iri(Iri<String>),
57    /// An anonymous-individual-valued annotation.
58    AnonymousIndividual(B),
59    /// A literal-valued annotation.
60    Literal(L),
61}
62
63impl<L, B> AnnotationValue<L, B> {
64    /// Construct an annotation value from a caller-owned anonymous identity.
65    #[must_use]
66    pub fn anonymous_individual(identity: B) -> Self {
67        Self::AnonymousIndividual(identity)
68    }
69}
70
71/// Subject of an OWL annotation assertion.
72#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
73#[serde(deny_unknown_fields)]
74pub enum AnnotationSubject<B = BlankNodeId> {
75    /// An IRI subject.
76    Iri(Iri<String>),
77    /// An anonymous individual subject.
78    AnonymousIndividual(B),
79}
80
81/// Axiom annotations attached to one structural axiom.
82#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
83#[serde(deny_unknown_fields)]
84pub struct AxiomAnnotations<L = OwlLiteral, B = BlankNodeId> {
85    // bounded: annotations belong to one structural axiom.
86    annotations: OperandSet<Annotation<L, B>>,
87}
88
89impl<L, B> AxiomAnnotations<L, B> {
90    /// Create an empty annotation set.
91    #[must_use]
92    pub fn empty() -> Self {
93        Self::default()
94    }
95
96    /// Create annotations from a bounded axiom-local collection.
97    #[must_use]
98    pub fn new(annotations: Vec<Annotation<L, B>>) -> Self {
99        Self {
100            annotations: OperandSet::new(annotations),
101        }
102    }
103
104    /// Return the annotations.
105    #[must_use]
106    pub fn as_slice(&self) -> &[Annotation<L, B>] {
107        self.annotations.as_slice()
108    }
109
110    /// Return the annotation count.
111    #[must_use]
112    pub fn len(&self) -> usize {
113        self.annotations.len()
114    }
115
116    /// Return whether no annotations are present.
117    #[must_use]
118    pub fn is_empty(&self) -> bool {
119        self.annotations.is_empty()
120    }
121}
122
123impl<L, B> Default for AxiomAnnotations<L, B> {
124    fn default() -> Self {
125        Self {
126            annotations: OperandSet::new(Vec::new()),
127        }
128    }
129}