Skip to main content

owl_structural_model/
lib.rs

1#![doc = include_str!("../README.md")]
2#![forbid(unsafe_code)]
3
4//! Typed OWL 2 structural values without an RDF-store dependency.
5
6mod annotation;
7mod annotation_axiom;
8mod assertion;
9mod axiom;
10mod axiom_annotations;
11mod cardinality;
12mod class_axiom;
13mod class_boolean;
14mod class_expression;
15mod class_restriction;
16mod data_axiom;
17mod data_range;
18mod entity;
19mod error;
20mod individual;
21mod key;
22mod kind;
23mod ontology;
24mod operand_set;
25mod operands;
26mod patch;
27mod property_axiom;
28mod property_chain;
29mod property_schema;
30mod vocabulary;
31
32pub use annotation::{Annotation, AnnotationSubject, AnnotationValue, AxiomAnnotations};
33pub use axiom::Axiom;
34pub use cardinality::Cardinality;
35pub use class_expression::{ClassExpression, ObjectPropertyExpression};
36pub use data_range::{DataRange, FacetRestriction};
37pub use entity::{Entity, EntityKind};
38pub use error::StructuralModelError;
39pub use individual::Individual;
40pub use key::KeyProperties;
41pub use kind::{AxiomKind, ClassExpressionKind, DataRangeKind};
42pub use ontology::{OntologyId, OntologyIdentity};
43pub use operand_set::{OperandSet, UnorderedPair};
44pub use operands::OperandList;
45pub use patch::{OntologyPatch, OntologyPatchOperation};
46pub use property_chain::{ObjectPropertyChain, SubObjectPropertyExpression};
47pub use rdf_structural_model::{BlankNodeId, Literal as OwlLiteral};
48pub use vocabulary::{OWL_NOTHING, OWL_THING, RDFS_LITERAL};
49
50#[cfg(test)]
51mod tests {
52    use iri_rfc3987::Iri;
53
54    use super::*;
55    type ClassExpression = super::ClassExpression;
56
57    fn iri(value: &str) -> Iri<String> {
58        Iri::parse(value).expect("test IRI is valid").into()
59    }
60
61    #[test]
62    fn constructors_preserve_structural_shape() {
63        let axiom: Axiom = Axiom::sub_class_of(
64            ClassExpression::named(iri("https://example.org/Customer")),
65            ClassExpression::named(iri("https://example.org/Party")),
66        );
67
68        assert!(matches!(axiom, Axiom::SubClassOf { .. }));
69        assert_eq!(
70            Entity::class(iri("https://example.org/Customer")).kind(),
71            EntityKind::Class
72        );
73    }
74
75    #[test]
76    fn invalid_structural_values_fail_at_construction() {
77        let error = ClassExpression::object_union_of(Vec::new()).unwrap_err();
78        assert!(matches!(error, StructuralModelError::InvalidFormat { .. }));
79
80        assert!(rdf_structural_model::LanguageTag::try_new("").is_err());
81    }
82
83    #[test]
84    fn ontology_identity_rejects_version_without_name() {
85        let error = OntologyId::try_new(None, Some(iri("https://example.org/v1"))).unwrap_err();
86        assert!(matches!(error, StructuralModelError::InvalidFormat { .. }));
87    }
88
89    /// ```
90    /// use iri_rfc3987::Iri;
91    /// use owl_structural_model::{Axiom, ClassExpression};
92    ///
93    /// let parse = |value: &str| Iri::parse(value).expect("valid IRI").into();
94    /// let axiom: Axiom = Axiom::sub_class_of(
95    ///     ClassExpression::named(parse("https://example.org/Customer")),
96    ///     ClassExpression::named(parse("https://example.org/Party")),
97    /// );
98    /// assert!(matches!(axiom, Axiom::SubClassOf { .. }));
99    /// ```
100    #[test]
101    fn doctest_anchor() {}
102}