Skip to main content

owl_structural_model/
key.rs

1//! Structural key properties, independent of RDF list representation.
2
3use iri_rfc3987::Iri;
4
5use crate::{ObjectPropertyExpression, StructuralModelError};
6
7/// The object and data properties identifying instances in one `HasKey` axiom.
8///
9/// Either list can be empty; together they must contain at least one property.
10/// Object and data properties remain separate even if their IRIs coincide.
11#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
12#[serde(try_from = "KeyPropertiesInput")]
13pub struct KeyProperties {
14    // bounded: object properties in one caller-owned structural key axiom.
15    object_properties: Vec<ObjectPropertyExpression>,
16    // bounded: data properties in one caller-owned structural key axiom.
17    data_properties: Vec<Iri<String>>,
18}
19
20impl KeyProperties {
21    /// Create key properties while preserving the two property categories.
22    ///
23    /// # Errors
24    ///
25    /// Returns [`StructuralModelError::InvalidFormat`] when both lists are empty.
26    pub fn try_new(
27        object_properties: Vec<ObjectPropertyExpression>,
28        data_properties: Vec<Iri<String>>,
29    ) -> Result<Self, StructuralModelError> {
30        if object_properties.is_empty() && data_properties.is_empty() {
31            return Err(StructuralModelError::InvalidFormat {
32                kind: "key properties",
33                value: "0".to_owned(),
34                message: "requires at least one key property",
35            });
36        }
37        Ok(Self {
38            object_properties,
39            data_properties,
40        })
41    }
42
43    /// Return the object property expressions.
44    #[must_use]
45    pub fn object_properties(&self) -> &[ObjectPropertyExpression] {
46        &self.object_properties
47    }
48
49    /// Return the named data properties.
50    #[must_use]
51    pub fn data_properties(&self) -> &[Iri<String>] {
52        &self.data_properties
53    }
54}
55
56#[derive(serde::Deserialize)]
57struct KeyPropertiesInput {
58    // bounded: object properties of one deserialized structural key axiom.
59    object_properties: Vec<ObjectPropertyExpression>,
60    // bounded: data properties of one deserialized structural key axiom.
61    data_properties: Vec<Iri<String>>,
62}
63
64impl TryFrom<KeyPropertiesInput> for KeyProperties {
65    type Error = StructuralModelError;
66
67    fn try_from(input: KeyPropertiesInput) -> Result<Self, Self::Error> {
68        Self::try_new(input.object_properties, input.data_properties)
69    }
70}