fastobo/ast/typedef/
frame.rs

1use std::fmt::Display;
2use std::fmt::Formatter;
3use std::fmt::Result as FmtResult;
4use std::ops::Deref;
5use std::ops::DerefMut;
6
7use fastobo_derive_internal::FromStr;
8
9use crate::ast::*;
10use crate::error::SyntaxError;
11use crate::parser::Cache;
12use crate::parser::FromPair;
13use crate::semantics::Identified;
14use crate::semantics::OboFrame;
15use crate::semantics::Orderable;
16use crate::syntax::pest::iterators::Pair;
17use crate::syntax::Rule;
18
19/// A typedef clause, describing a relationship.
20#[derive(Clone, Debug, Eq, FromStr, Hash, PartialEq)]
21pub struct TypedefFrame {
22    id: Line<RelationIdent>,
23    clauses: Vec<Line<TypedefClause>>,
24}
25
26impl TypedefFrame {
27    /// Create a new typedef frame with the given identifier.
28    pub fn new<I>(id: I) -> Self
29    where
30        I: Into<Line<RelationIdent>>,
31    {
32        Self::with_clauses(id, Vec::new())
33    }
34
35    /// Create a new typedef frame from an identifier and a vector of clauses.
36    pub fn with_clauses<I>(id: I, clauses: Vec<Line<TypedefClause>>) -> Self
37    where
38        I: Into<Line<RelationIdent>>,
39    {
40        Self {
41            id: id.into(),
42            clauses,
43        }
44    }
45
46    /// Get a reference to the identifier of the `TypedefFrame`.
47    pub fn id(&self) -> &Line<RelationIdent> {
48        &self.id
49    }
50
51    /// Get a mutable reference to the identifier of the `TypedefFrame`.
52    pub fn id_mut(&mut self) -> &mut Line<RelationIdent> {
53        &mut self.id
54    }
55
56    /// Get the `TypedefClause`s of the `TypedefFrame`.
57    pub fn clauses(&self) -> &Vec<Line<TypedefClause>> {
58        &self.clauses
59    }
60
61    /// Get a mutable reference to the `TypedefClause`s of the `TypedefFrame`.
62    pub fn clauses_mut(&mut self) -> &mut Vec<Line<TypedefClause>> {
63        &mut self.clauses
64    }
65
66    /// Get the name of the typedef, if exactly one is declared.
67    pub fn name(&self) -> Result<&UnquotedString, CardinalityError> {
68        let mut name: Option<&UnquotedString> = None;
69        for clause in &self.clauses {
70            if let TypedefClause::Name(n) = clause.as_inner() {
71                match name {
72                    Some(_) => return Err(CardinalityError::duplicate("name")),
73                    None => name = Some(n),
74                }
75            }
76        }
77        name.ok_or_else(|| CardinalityError::missing("name"))
78    }
79
80    /// Get the definition of the typedef, if exactly one is declared.
81    pub fn definition(&self) -> Result<&Definition, CardinalityError> {
82        let mut def: Option<&Definition> = None;
83        for clause in &self.clauses {
84            if let TypedefClause::Def(n) = clause.as_inner() {
85                match def {
86                    Some(_) => return Err(CardinalityError::duplicate("def")),
87                    None => def = Some(n),
88                }
89            }
90        }
91        def.ok_or_else(|| CardinalityError::missing("def"))
92    }
93}
94
95impl AsRef<Vec<Line<TypedefClause>>> for TypedefFrame {
96    fn as_ref(&self) -> &Vec<Line<TypedefClause>> {
97        &self.clauses
98    }
99}
100
101impl AsRef<[Line<TypedefClause>]> for TypedefFrame {
102    fn as_ref(&self) -> &[Line<TypedefClause>] {
103        &self.clauses
104    }
105}
106
107impl Deref for TypedefFrame {
108    type Target = Vec<Line<TypedefClause>>;
109    fn deref(&self) -> &Self::Target {
110        &self.clauses
111    }
112}
113
114impl DerefMut for TypedefFrame {
115    fn deref_mut(&mut self) -> &mut Self::Target {
116        &mut self.clauses
117    }
118}
119
120impl Display for TypedefFrame {
121    fn fmt(&self, f: &mut Formatter) -> FmtResult {
122        f.write_str("[Typedef]\nid: ").and(self.id.fmt(f))?;
123        self.clauses.iter().try_for_each(|clause| clause.fmt(f))
124    }
125}
126
127impl Identified for TypedefFrame {
128    /// Get a reference to the identifier of the term.
129    fn as_id(&self) -> &Ident {
130        self.id.as_inner().as_ref()
131    }
132
133    /// Get a mutable reference to the identifier of the term.
134    fn as_id_mut(&mut self) -> &mut Ident {
135        self.id.as_mut().as_mut()
136    }
137}
138
139impl<'i> FromPair<'i> for TypedefFrame {
140    const RULE: Rule = Rule::TypedefFrame;
141    unsafe fn from_pair_unchecked(
142        pair: Pair<'i, Rule>,
143        cache: &Cache,
144    ) -> Result<Self, SyntaxError> {
145        let mut inner = pair.into_inner();
146        let relid = RelationIdent::from_pair_unchecked(inner.next().unwrap(), cache)?;
147        let id = Eol::from_pair_unchecked(inner.next().unwrap(), cache)?.and_inner(relid);
148
149        let mut clauses = Vec::new();
150        for pair in inner {
151            clauses.push(Line::<TypedefClause>::from_pair_unchecked(pair, cache)?);
152        }
153
154        Ok(TypedefFrame { id, clauses })
155    }
156}
157
158impl IntoIterator for TypedefFrame {
159    type Item = Line<TypedefClause>;
160    type IntoIter = <Vec<Line<TypedefClause>> as IntoIterator>::IntoIter;
161    fn into_iter(self) -> Self::IntoIter {
162        self.clauses.into_iter()
163    }
164}
165
166impl<'a> IntoIterator for &'a TypedefFrame {
167    type Item = &'a Line<TypedefClause>;
168    type IntoIter = <&'a Vec<Line<TypedefClause>> as IntoIterator>::IntoIter;
169    fn into_iter(self) -> Self::IntoIter {
170        self.clauses.as_slice().iter()
171    }
172}
173
174impl Orderable for TypedefFrame {
175    fn sort(&mut self) {
176        self.clauses.sort_unstable();
177    }
178    fn is_sorted(&self) -> bool {
179        for i in 1..self.clauses.len() {
180            if self.clauses[i - 1] > self.clauses[i] {
181                return false;
182            }
183        }
184        true
185    }
186}
187
188impl OboFrame for TypedefFrame {
189    type Clause = TypedefClause;
190
191    fn clauses_ref(&self) -> Vec<&Self::Clause> {
192        self.clauses.iter().map(Line::as_inner).collect()
193    }
194}