flams_ontology/uris/
terms.rs

1use crate::uris::{
2    debugdisplay, ContentURI, DocumentElementURI, NameStep, NarrativeURI, SymbolURI, URIParseError,
3    URI,
4};
5use smallvec::SmallVec;
6use std::fmt::Display;
7use std::str::FromStr;
8
9#[derive(Clone, PartialEq, Eq, Hash)]
10pub enum TermURI {
11    SymbolTp(SymbolURI),
12    SymbolDf(SymbolURI),
13    VariableTp(DocumentElementURI),
14    VariableDf(DocumentElementURI),
15    DocumentTerm(DocumentElementURI),
16}
17impl TermURI {
18    #[must_use]
19    #[allow(clippy::missing_const_for_fn)]
20    pub fn as_ref(&self) -> TermURIRef {
21        match self {
22            Self::SymbolTp(uri) => TermURIRef::SymbolTp(uri),
23            Self::SymbolDf(uri) => TermURIRef::SymbolDf(uri),
24            Self::VariableTp(uri) => TermURIRef::VariableTp(uri),
25            Self::VariableDf(uri) => TermURIRef::VariableDf(uri),
26            Self::DocumentTerm(uri) => TermURIRef::DocumentTerm(uri),
27        }
28    }
29}
30#[derive(Clone, Copy, PartialEq, Eq, Hash)]
31pub enum TermURIRef<'a> {
32    SymbolTp(&'a SymbolURI),
33    SymbolDf(&'a SymbolURI),
34    VariableTp(&'a DocumentElementURI),
35    VariableDf(&'a DocumentElementURI),
36    DocumentTerm(&'a DocumentElementURI),
37}
38#[derive(Clone, PartialEq, Eq, Hash)]
39pub struct SubTermIndex(SmallVec<u16, 8>);
40
41#[derive(Clone, PartialEq, Eq, Hash)]
42pub struct SubTermURI {
43    uri: TermURI,
44    subterm: SubTermIndex,
45}
46
47impl Display for TermURIRef<'_> {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        match *self {
50            Self::SymbolTp(uri) => write!(f, "{uri}&tp"),
51            Self::SymbolDf(uri) => write!(f, "{uri}&df"),
52            Self::VariableTp(uri) => write!(f, "{uri}&tp"),
53            Self::VariableDf(uri) => write!(f, "{uri}&df"),
54            Self::DocumentTerm(uri) => Display::fmt(uri, f),
55        }
56    }
57}
58debugdisplay!(TermURIRef<'_>);
59impl Display for TermURI {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        Display::fmt(&self.as_ref(), f)
62    }
63}
64debugdisplay!(TermURI);
65impl FromStr for TermURI {
66    type Err = URIParseError;
67    fn from_str(s: &str) -> Result<Self, Self::Err> {
68        macro_rules! symordoc {
69            ($s:ident,$tp:ident) => {
70                paste::paste!{
71                    match URI::from_str($s)? {
72                        URI::Narrative(NarrativeURI::Element(uri)) => Ok(Self::[<Variable $tp>](uri)),
73                        URI::Content(ContentURI::Symbol(uri)) => Ok(Self::[<Symbol $tp>](uri)),
74                        _ => Err(URIParseError::UnrecognizedPart {
75                            original:s.to_string()
76                        })
77                    }
78                }
79            }
80        }
81        s.strip_suffix("&tp").map_or_else(
82            || {
83                s.strip_suffix("&df").map_or_else(
84                    || DocumentElementURI::from_str(s).map(TermURI::DocumentTerm),
85                    |s| symordoc!(s, Df),
86                )
87            },
88            |s| symordoc!(s, Tp),
89        )
90    }
91}