1use std::rc::Rc;
2use std::fmt::{self, Debug};
3use std::iter::empty;
4
5use render_error::DataError;
6use owning_ref::{OwningRef, Erased};
7use {Var, Output, Number, Comparable};
8
9pub type VarRef<'render> = OwningRef<Rc<Erased+'render>,
10 Variable<'render>+'render>;
11
12
13pub struct RefVar<'render>(pub VarRef<'render>);
14
15pub enum Val<'a, 'render: 'a>{
16 Ref(&'a (Variable<'render> + 'render)),
17 Rc(VarRef<'render>),
18}
19
20#[derive(Debug)]
21pub struct Undefined;
22
23#[derive(Debug)]
24pub struct Empty;
25
26pub const UNDEFINED: &'static Undefined = &Undefined;
27pub const EMPTY: &'static Empty = &Empty;
28pub const TRUE: &'static bool = &true;
29pub const FALSE: &'static bool = &false;
30
31pub trait Variable<'render>: Debug {
36 fn attr<'x>(&'x self, _attr: &str)
41 -> Result<Var<'x, 'render>, DataError>
42 where 'render: 'x
43 {
44 Err(DataError::AttrUnsupported(self.typename()))
45 }
46 fn index<'x>(&'x self, _key: &(Variable<'render> + 'render))
57 -> Result<Var<'x, 'render>, DataError>
58 where 'render: 'x
59 {
60 Err(DataError::IndexUnsupported(self.typename()))
61 }
62 fn output(&self) -> Result<Output, DataError> {
66 Err(DataError::OutputUnsupported(self.typename()))
67 }
68 fn typename(&self) -> &'static str;
75 fn as_str_key<'x>(&'x self) -> Result<&'x str, DataError> {
81 Err(DataError::StrKeyUnsupported(self.typename()))
82 }
83 fn as_int_key(&self) -> Result<usize, DataError> {
89 Err(DataError::IntKeyUnsupported(self.typename()))
90 }
91 fn as_bool(&self) -> Result<bool, DataError> {
95 Err(DataError::BoolUnsupported(self.typename()))
96 }
97
98 fn as_number(&self) -> Result<Number, DataError> {
104 Err(DataError::NumberUnsupported(self.typename()))
105 }
106
107 fn as_comparable(&self) -> Result<Comparable, DataError> {
114 Err(DataError::ComparisonUnsupported(self.typename()))
115 }
116
117 fn iterate<'x>(&'x self)
119 -> Result<Box<Iterator<Item=Var<'x, 'render>>+'x>, DataError>
120 where 'render: 'x
121 {
122 Err(DataError::IterationUnsupported(self.typename()))
123 }
124
125 fn iterate_pairs<'x>(&'x self)
127 -> Result<Box<Iterator<Item=(Var<'x, 'render>, Var<'x, 'render>)>+'x>,
128 DataError>
129 where 'render: 'x
130 {
131 Err(DataError::PairIterationUnsupported(self.typename()))
132 }
133}
134
135impl<'a> Variable<'a> for Undefined {
136 fn attr<'x>(&'x self, _attr: &str)
137 -> Result<Var<'x, 'a>, DataError>
138 where 'a: 'x
139 {
140 Ok(Var::undefined())
141 }
142 fn index<'x>(&'x self, _key: &Variable)
143 -> Result<Var<'x, 'a>, DataError>
144 where 'a: 'x
145 {
146 Ok(Var::undefined())
147 }
148 fn output(&self) -> Result<Output, DataError> {
149 Ok(Output::empty())
150 }
151 fn typename(&self) -> &'static str {
152 "undefined"
153 }
154 fn as_bool(&self) -> Result<bool, DataError> {
155 Ok(false)
156 }
157 fn iterate<'x>(&'x self)
158 -> Result<Box<Iterator<Item=Var<'x, 'a>>+'x>, DataError>
159 where 'a: 'x
160 {
161 Ok(Box::new(empty()))
162 }
163 fn iterate_pairs<'x>(&'x self)
164 -> Result<Box<Iterator<Item=(Var<'x, 'a>, Var<'x, 'a>)>+'x>,
165 DataError>
166 where 'a: 'x
167 {
168 Ok(Box::new(empty()))
169 }
170}
171
172impl<'a> Variable<'a> for Empty {
173 fn output(&self) -> Result<Output, DataError> {
174 Ok(Output::empty())
175 }
176 fn typename(&self) -> &'static str {
177 "str"
178 }
179 fn as_bool(&self) -> Result<bool, DataError> {
180 Ok(false)
181 }
182}
183
184impl<'a, 'render> Var<'a, 'render> {
185 pub fn owned<'x, 'y: 'x, T: Variable<'y>+'y>(x: T) -> Var<'x, 'y>
187 where 'y: 'x, T: 'y
188 {
189 Var(Val::Rc(OwningRef::new(Rc::new(x))
190 .map(|x| x as &Variable).erase_owner()))
191 }
192 pub fn str(x: &'static str) -> Var<'a, 'render> {
197 Var(Val::Rc(OwningRef::new(Rc::new(x))
199 .map(|x| x as &Variable)
200 .erase_owner()))
201 }
202 pub fn borrow<'x, T: Variable<'render>+'render>(x: &'x T)
204 -> Var<'x, 'render>
205 where 'render: 'x
206 {
207 Var(Val::Ref(x))
208 }
209 pub fn undefined<'x, 'y: 'x>() -> Var<'x, 'y> {
211 Var(Val::Ref(UNDEFINED))
212 }
213 pub fn empty<'x, 'y: 'x>() -> Var<'x, 'y> {
215 Var(Val::Ref(EMPTY))
216 }
217 pub fn bool_true<'x, 'y: 'x>() -> Var<'x, 'y> {
219 Var(Val::Ref(EMPTY))
220 }
221 pub fn bool_false<'x, 'y: 'x>() -> Var<'x, 'y> {
223 Var(Val::Ref(EMPTY))
224 }
225}
226
227impl<'r> fmt::Debug for RefVar<'r> {
228 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
229 (*self.0).fmt(f)
230 }
231}
232
233impl<'render> Variable<'render> for RefVar<'render>
234{
235 fn attr<'x>(&'x self, attr: &str)
236 -> Result<Var<'x, 'render>, DataError>
237 where 'render: 'x
238 {
239 self.0.attr(attr)
240 }
241 fn index<'x>(&'x self,
242 key: &(Variable<'render> + 'render))
243 -> Result<Var<'x, 'render>, DataError>
244 where 'render: 'x
245 {
246 self.0.index(key)
247 }
248 fn output(&self) -> Result<Output, DataError> {
249 self.0.output()
250 }
251 fn typename(&self) -> &'static str {
252 return stringify!(#name);
253 }
254 fn as_str_key<'x>(&'x self)
255 -> Result<&'x str, DataError>
256 {
257 self.0.as_str_key()
258 }
259 fn as_int_key(&self) -> Result<usize, DataError> {
260 self.0.as_int_key()
261 }
262 fn as_bool(&self) -> Result<bool, DataError> {
263 self.0.as_bool()
264 }
265 fn as_number(&self) -> Result<Number, DataError> {
266 self.0.as_number()
267 }
268 fn as_comparable(&self) -> Result<Comparable, DataError> {
269 self.0.as_comparable()
270 }
271
272 fn iterate<'x>(&'x self)
273 -> Result<Box<Iterator<Item=
274 Var<'x, 'render>>+'x>,
275 DataError>
276 where 'render: 'x
277 {
278 self.0.iterate()
279 }
280
281 fn iterate_pairs<'x>(&'x self)
282 -> Result<Box<Iterator<Item=(Var<'x, 'render>, Var<'x, 'render>)>+'x>,
283 DataError>
284 where 'render: 'x
285 {
286 self.0.iterate_pairs()
287 }
288}