fastobo/ast/typedef/
frame.rs1use 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#[derive(Clone, Debug, Eq, FromStr, Hash, PartialEq)]
21pub struct TypedefFrame {
22 id: Line<RelationIdent>,
23 clauses: Vec<Line<TypedefClause>>,
24}
25
26impl TypedefFrame {
27 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 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 pub fn id(&self) -> &Line<RelationIdent> {
48 &self.id
49 }
50
51 pub fn id_mut(&mut self) -> &mut Line<RelationIdent> {
53 &mut self.id
54 }
55
56 pub fn clauses(&self) -> &Vec<Line<TypedefClause>> {
58 &self.clauses
59 }
60
61 pub fn clauses_mut(&mut self) -> &mut Vec<Line<TypedefClause>> {
63 &mut self.clauses
64 }
65
66 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 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 fn as_id(&self) -> &Ident {
130 self.id.as_inner().as_ref()
131 }
132
133 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}