flams_ontology/content/declarations/
symbols.rs

1use smallvec::SmallVec;
2use std::str::FromStr;
3
4use crate::{
5    content::terms::{ArgMode, Term},
6    uris::SymbolURI,
7    Resolvable,
8};
9
10use super::{Declaration, DeclarationTrait};
11
12#[derive(Debug, Clone)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14pub struct Symbol {
15    pub uri: SymbolURI,
16    pub arity: ArgSpec,
17    pub macroname: Option<Box<str>>,
18    pub role: Box<[Box<str>]>,
19    pub tp: Option<Term>,
20    pub df: Option<Term>,
21    pub assoctype: Option<AssocType>,
22    pub reordering: Option<Box<str>>,
23}
24impl Resolvable for Symbol {
25    type From = SymbolURI;
26    fn id(&self) -> std::borrow::Cow<'_, Self::From> {
27        std::borrow::Cow::Borrowed(&self.uri)
28    }
29}
30impl super::private::Sealed for Symbol {}
31impl DeclarationTrait for Symbol {
32    #[inline]
33    fn from_declaration(decl: &Declaration) -> Option<&Self> {
34        match decl {
35            Declaration::Symbol(m) => Some(m),
36            _ => None,
37        }
38    }
39}
40
41#[derive(Debug, Copy, Clone)]
42#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
43#[non_exhaustive]
44pub enum AssocType {
45    LeftAssociativeBinary,
46    RightAssociativeBinary,
47    Conjunctive,
48    PairwiseConjunctive,
49    Prenex,
50}
51impl FromStr for AssocType {
52    type Err = ();
53    fn from_str(s: &str) -> Result<Self, Self::Err> {
54        match s {
55            "binl" | "bin" => Ok(Self::LeftAssociativeBinary),
56            "binr" => Ok(Self::RightAssociativeBinary),
57            "conj" => Ok(Self::Conjunctive),
58            "pwconj" => Ok(Self::PairwiseConjunctive),
59            "pre" => Ok(Self::Prenex),
60            _ => Err(()),
61        }
62    }
63}
64
65#[derive(Debug, Clone)]
66#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
67#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify))]
68#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
69pub struct ArgSpec(#[cfg_attr(feature = "wasm", tsify(type = "ArgMode[]"))] SmallVec<ArgMode, 9>);
70impl IntoIterator for ArgSpec {
71    type Item = ArgMode;
72    type IntoIter = smallvec::IntoIter<ArgMode, 9>;
73    fn into_iter(self) -> Self::IntoIter {
74        self.0.into_iter()
75    }
76}
77
78impl ArgSpec {
79    #[inline]
80    #[allow(clippy::cast_possible_truncation)]
81    #[must_use]
82    pub const fn num(&self) -> u8 {
83        self.0.len() as u8
84    }
85}
86
87impl Default for ArgSpec {
88    #[inline]
89    fn default() -> Self {
90        Self(SmallVec::new())
91    }
92}
93
94impl FromStr for ArgSpec {
95    type Err = ();
96    fn from_str(s: &str) -> Result<Self, ()> {
97        if let Ok(u) = s.parse::<u8>() {
98            return Ok(Self((0..u).map(|_| ArgMode::Normal).collect()));
99        }
100        let mut ret = SmallVec::new();
101        for c in s.bytes() {
102            ret.push(match c {
103                b'i' => ArgMode::Normal,
104                b'a' => ArgMode::Sequence,
105                b'b' => ArgMode::Binding,
106                b'B' => ArgMode::BindingSequence,
107                _ => return Err(()),
108            });
109        }
110        Ok(Self(ret))
111    }
112}