Skip to main content

owl_structural_model/
literal.rs

1//! OWL literal values.
2
3use iri_rfc3987::Iri;
4
5use crate::StructuralModelError;
6
7const KIND_LANGUAGE_TAG: &str = "language tag";
8
9/// A literal value used in OWL structural annotations and axioms.
10#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
11pub enum OwlLiteral {
12    /// A typed literal.
13    Typed {
14        /// Literal lexical form.
15        lexical: String,
16        /// Literal datatype IRI.
17        datatype: Iri<String>,
18    },
19    /// A language-tagged string literal.
20    LanguageTagged {
21        /// Literal lexical form.
22        lexical: String,
23        /// BCP-47 language tag.
24        language: String,
25    },
26}
27
28impl OwlLiteral {
29    /// Create a typed literal.
30    #[must_use]
31    pub fn typed(lexical: impl Into<String>, datatype: Iri<String>) -> Self {
32        Self::Typed {
33            lexical: lexical.into(),
34            datatype,
35        }
36    }
37
38    /// Create a language-tagged literal.
39    ///
40    /// # Errors
41    ///
42    /// Returns [`StructuralModelError::Empty`] when the language tag is empty.
43    pub fn language_tagged(
44        lexical: impl Into<String>,
45        language: impl Into<String>,
46    ) -> Result<Self, StructuralModelError> {
47        let language = language.into();
48        if language.is_empty() {
49            return Err(StructuralModelError::Empty {
50                kind: KIND_LANGUAGE_TAG,
51            });
52        }
53        Ok(Self::LanguageTagged {
54            lexical: lexical.into(),
55            language,
56        })
57    }
58}