owl_structural_model/
data_range.rs1use iri_rfc3987::Iri;
4
5use crate::{OwlLiteral, StructuralModelError};
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
12pub struct FacetRestriction<L = OwlLiteral> {
13 facet: Iri<String>,
14 value: L,
15}
16
17impl<L> FacetRestriction<L> {
18 #[must_use]
20 pub fn new(facet: Iri<String>, value: L) -> Self {
21 Self { facet, value }
22 }
23
24 #[must_use]
26 pub fn facet(&self) -> &Iri<String> {
27 &self.facet
28 }
29
30 #[must_use]
32 pub fn value(&self) -> &L {
33 &self.value
34 }
35}
36
37#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
39#[serde(
40 try_from = "DataRangeInput<L>",
41 bound(deserialize = "L: serde::Deserialize<'de>")
42)]
43pub enum DataRange<L = OwlLiteral> {
44 Datatype(Iri<String>),
46 DataIntersectionOf(Vec<Self>),
49 DataUnionOf(Vec<Self>),
52 DataComplementOf(Box<Self>),
54 DataOneOf(Vec<L>),
57 DatatypeRestriction {
59 datatype: Iri<String>,
61 restrictions: Vec<FacetRestriction<L>>,
64 },
65}
66
67impl<L> DataRange<L> {
68 #[must_use]
70 pub fn datatype(datatype: Iri<String>) -> Self {
71 Self::Datatype(datatype)
72 }
73
74 pub fn data_intersection_of(operands: Vec<Self>) -> Result<Self, StructuralModelError> {
80 Self::require_count(operands.len(), 2, "data intersection")?;
81 Ok(Self::DataIntersectionOf(operands))
82 }
83
84 pub fn data_union_of(operands: Vec<Self>) -> Result<Self, StructuralModelError> {
90 Self::require_count(operands.len(), 2, "data union")?;
91 Ok(Self::DataUnionOf(operands))
92 }
93
94 #[must_use]
96 pub fn data_complement_of(operand: Self) -> Self {
97 Self::DataComplementOf(Box::new(operand))
98 }
99
100 pub fn data_one_of(literals: Vec<L>) -> Result<Self, StructuralModelError> {
106 Self::require_count(literals.len(), 1, "data enumeration")?;
107 Ok(Self::DataOneOf(literals))
108 }
109
110 pub fn datatype_restriction(
116 datatype: Iri<String>,
117 restrictions: Vec<FacetRestriction<L>>,
118 ) -> Result<Self, StructuralModelError> {
119 Self::require_count(restrictions.len(), 1, "datatype restriction")?;
120 Ok(Self::DatatypeRestriction {
121 datatype,
122 restrictions,
123 })
124 }
125
126 fn require_count(
127 count: usize,
128 minimum: usize,
129 kind: &'static str,
130 ) -> Result<(), StructuralModelError> {
131 if count < minimum {
132 return Err(StructuralModelError::InvalidFormat {
133 kind,
134 value: count.to_string(),
135 message: if minimum == 1 {
136 "requires at least one operand"
137 } else {
138 "requires at least two operands"
139 },
140 });
141 }
142 Ok(())
143 }
144}
145
146#[derive(serde::Deserialize)]
149enum DataRangeInput<L> {
150 Datatype(Iri<String>),
151 DataIntersectionOf(Vec<DataRange<L>>),
153 DataUnionOf(Vec<DataRange<L>>),
155 DataComplementOf(Box<DataRange<L>>),
156 DataOneOf(Vec<L>),
158 DatatypeRestriction {
159 datatype: Iri<String>,
160 restrictions: Vec<FacetRestriction<L>>,
162 },
163}
164
165impl<L> TryFrom<DataRangeInput<L>> for DataRange<L> {
166 type Error = StructuralModelError;
167
168 fn try_from(input: DataRangeInput<L>) -> Result<Self, Self::Error> {
169 match input {
170 DataRangeInput::Datatype(datatype) => Ok(Self::datatype(datatype)),
171 DataRangeInput::DataIntersectionOf(operands) => Self::data_intersection_of(operands),
172 DataRangeInput::DataUnionOf(operands) => Self::data_union_of(operands),
173 DataRangeInput::DataComplementOf(operand) => Ok(Self::DataComplementOf(operand)),
174 DataRangeInput::DataOneOf(literals) => Self::data_one_of(literals),
175 DataRangeInput::DatatypeRestriction {
176 datatype,
177 restrictions,
178 } => Self::datatype_restriction(datatype, restrictions),
179 }
180 }
181}