1use std::fmt::Display;
2use std::fmt::Formatter;
3use std::fmt::Result as FmtResult;
4
5use super::EntityFrame;
6use super::HeaderFrame;
7use super::InstanceFrame;
8use super::TermFrame;
9use super::TypedefFrame;
10
11use crate::semantics::Orderable;
12
13#[derive(Debug, Clone, PartialEq)]
26pub enum Frame {
27    Header(Box<HeaderFrame>),
28    Typedef(Box<TypedefFrame>),
29    Term(Box<TermFrame>),
30    Instance(Box<InstanceFrame>),
31}
32
33impl Frame {
34    pub fn as_header(&self) -> Option<&HeaderFrame> {
38        if let Frame::Header(frame) = self {
39            Some(frame.as_ref())
40        } else {
41            None
42        }
43    }
44
45    pub fn as_header_mut(&mut self) -> Option<&mut HeaderFrame> {
49        if let Frame::Header(frame) = self {
50            Some(frame.as_mut())
51        } else {
52            None
53        }
54    }
55
56    pub fn as_term(&self) -> Option<&TermFrame> {
60        if let Frame::Term(frame) = self {
61            Some(frame.as_ref())
62        } else {
63            None
64        }
65    }
66
67    pub fn as_term_mut(&mut self) -> Option<&mut TermFrame> {
71        if let Frame::Term(frame) = self {
72            Some(frame.as_mut())
73        } else {
74            None
75        }
76    }
77
78    pub fn as_typedef(&self) -> Option<&TypedefFrame> {
82        if let Frame::Typedef(frame) = self {
83            Some(frame.as_ref())
84        } else {
85            None
86        }
87    }
88
89    pub fn as_typedef_mut(&mut self) -> Option<&mut TypedefFrame> {
93        if let Frame::Typedef(frame) = self {
94            Some(frame.as_mut())
95        } else {
96            None
97        }
98    }
99
100    pub fn as_instance(&self) -> Option<&InstanceFrame> {
104        if let Frame::Instance(frame) = self {
105            Some(frame.as_ref())
106        } else {
107            None
108        }
109    }
110
111    pub fn as_instance_mut(&mut self) -> Option<&mut InstanceFrame> {
115        if let Frame::Instance(frame) = self {
116            Some(frame.as_mut())
117        } else {
118            None
119        }
120    }
121
122    pub fn into_header(self) -> Option<HeaderFrame> {
124        if let Frame::Header(h) = self {
125            Some(*h)
126        } else {
127            None
128        }
129    }
130
131    pub fn into_entity(self) -> Option<EntityFrame> {
133        match self {
134            Frame::Term(f) => Some(EntityFrame::Term(f)),
135            Frame::Typedef(f) => Some(EntityFrame::Typedef(f)),
136            Frame::Instance(f) => Some(EntityFrame::Instance(f)),
137            Frame::Header(_) => None,
138        }
139    }
140}
141
142impl Display for Frame {
143    fn fmt(&self, f: &mut Formatter) -> FmtResult {
144        use self::Frame::*;
145        match self {
146            Header(h) => h.fmt(f),
147            Term(t) => t.fmt(f),
148            Typedef(t) => t.fmt(f),
149            Instance(i) => i.fmt(f),
150        }
151    }
152}
153
154impl From<HeaderFrame> for Frame {
155    fn from(frame: HeaderFrame) -> Self {
156        Frame::Header(Box::new(frame))
157    }
158}
159
160impl From<TermFrame> for Frame {
161    fn from(frame: TermFrame) -> Self {
162        Frame::Term(Box::new(frame))
163    }
164}
165
166impl From<TypedefFrame> for Frame {
167    fn from(frame: TypedefFrame) -> Self {
168        Frame::Typedef(Box::new(frame))
169    }
170}
171
172impl From<InstanceFrame> for Frame {
173    fn from(frame: InstanceFrame) -> Self {
174        Frame::Instance(Box::new(frame))
175    }
176}
177
178impl From<EntityFrame> for Frame {
179    fn from(frame: EntityFrame) -> Self {
180        match frame {
181            EntityFrame::Term(f) => Frame::Term(f),
182            EntityFrame::Instance(f) => Frame::Instance(f),
183            EntityFrame::Typedef(f) => Frame::Typedef(f),
184        }
185    }
186}
187
188impl Orderable for Frame {
189    fn sort(&mut self) {
190        use self::Frame::*;
191        match self {
192            Header(h) => h.sort(),
193            Term(t) => t.sort(),
194            Typedef(t) => t.sort(),
195            Instance(i) => i.sort(),
196        }
197    }
198    fn is_sorted(&self) -> bool {
199        use self::Frame::*;
200        match self {
201            Header(h) => h.is_sorted(),
202            Term(t) => t.is_sorted(),
203            Typedef(t) => t.is_sorted(),
204            Instance(i) => i.is_sorted(),
205        }
206    }
207}