1extern crate trees;
12use trees::{tr,Tree,Forest,Node};
13
14use std::fmt;
15use std::fmt::{Display,Formatter};
16
17pub type Id = &'static str;
18pub type Name = Option<String>;
19
20#[derive( Copy, Clone, Debug, PartialEq, Eq, Ord )]
21pub enum Type {
23 Unknown,
24 Struct, Enum,
25 Bool, I8, U8, I16, U16, I32, U32, I64, U64, I128, U128, F32, F64,
26 Range,
27 RefStr, String,
28 Array, Tuple, Vec,
29 CPtr, Ptr, NonNull, Ref, RefMut, Box, Rc,
30 Option, Result,
31 BTreeSet, HashSet,
32 BTreeMap, HashMap,
33}
34
35impl Type {
36 pub fn is_pointer( &self ) -> bool { *self >= Type::CPtr && *self <= Type::Rc }
38}
39
40use std::cmp::Ordering;
41use std::cmp::Ordering::*;
42
43impl PartialOrd for Type {
44 fn partial_cmp( &self, other: &Self ) -> Option<Ordering> {
45 let ( a, b ) = ( *self as usize, *other as usize );
46 if a < b {
47 Some( Less )
48 } else if a > b {
49 Some( Greater )
50 } else {
51 Some( Equal )
52 }
53 }
54}
55
56impl Display for Type { fn fmt( &self, f: &mut Formatter ) -> fmt::Result { write!( f, "{}", TYPE_STR[ *self as usize ])}}
57
58const TYPE_STR: [Id;35] = [
59 "?",
60 "struct", "enum",
61 "bool", "i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64", "i128", "u128", "f32", "f64",
62 "Range",
63 "&str", "String",
64 "[]", "()", "Vec",
65 "*const", "*mut", "NonNull", "&", "&mut", "Box", "Rc",
66 "Option", "Result",
67 "BTreeSet", "HashSet",
68 "BTreeMap", "HashMap",
69];
70
71pub type Expander = Option<fn() -> Schemas>;
73
74#[derive( Clone, Debug, PartialEq, Eq )]
76pub struct Field {
77 pub id : Id,
78 pub ty : Type,
79 pub tyname : Name,
80 pub expander : Expander,
81}
82
83impl Field {
84 pub fn new( id: Id, ty: Type, tyname: Name, expander: Expander ) -> Self {
85 Field { id, ty, tyname, expander }
86 }
87}
88
89#[derive( Clone, Debug, Eq, PartialEq )]
91pub struct Variant {
92 pub id : Id,
93 pub tyname : Name,
94}
95
96#[derive( Clone, Debug, PartialEq, Eq )]
98pub enum Member {
99 Field( Field ),
100 Variant( Variant ),
101}
102
103impl Member {
104 pub fn id( &self ) -> Id {
105 match *self {
106 Member::Field( ref field ) => field.id,
107 Member::Variant( ref variant ) => variant.id,
108 }
109 }
110}
111
112pub fn field( id: Id, ty: Type, tyname: Name, expander: Expander ) -> Schema { tr( Member::Field( Field::new( id, ty, tyname, expander )))}
114
115pub fn variant( id: Id ) -> Schema { tr( Member::Variant( Variant{ id, tyname: None }))}
117
118pub fn terminal( id: Id, ty: Type ) -> Schema {
120 tr( Member::Field( Field::new( id, ty,
121 Some( String::from( TYPE_STR[ ty as usize ])), None )))
122}
123
124impl Display for Member {
125 fn fmt( &self, f: &mut Formatter ) -> fmt::Result {
126 match *self {
127 Member::Field( ref field ) =>
128 write!( f, "{}:{}", field.id, &field.tyname.clone().unwrap_or_default() ),
129 Member::Variant( ref variant ) =>
130 write!( f, "{}|", variant.id ),
131 }
132 }
133}
134
135pub type Schema = Tree <Member>;
136pub type Schemas = Forest<Member>;
137
138pub trait Reflection {
140 fn ty() -> Type { Type::Unknown }
142
143 fn name() -> Name { Some( String::from( TYPE_STR[ Self::ty() as usize ]))}
145
146 fn schema( id: Id ) -> Schema;
148
149 fn members() -> Schemas { Schemas::new() }
151
152 fn schemata() -> Schema {
154 let mut schema = Self::schema( "_" );
155 expand( &mut schema );
156 schema
157 }
158}
159
160#[allow( unused_must_use )]
162pub fn expand( node: &mut Node<Member> ) {
163 expand_field( node ) || expand_variant( node );
164}
165
166fn expand_field( node: &mut Node<Member> ) -> bool {
167 let mut expander: Expander = None;
168 if let Member::Field( ref field ) = node.data {
169 if node.is_leaf() && !field.ty.is_pointer() {
170 expander = field.expander;
171 }
172 }
173 expander.map( |expander| {
174 node.append( expander() );
175 for mut child in node.iter_mut() {
176 expand( &mut child );
177 }
178 true
179 }).unwrap_or( false )
180}
181
182fn expand_variant( node: &mut Node<Member> ) -> bool {
183 if let Member::Variant(_) = &mut node.data {
184 for mut child in node.iter_mut() {
185 expand_field( &mut child );
186 }
187 true
188 } else {
189 false
190 }
191}
192
193macro_rules! ty {
194 ($t:ty) => { <$t as Reflection>::ty() }
195}
196
197macro_rules! name {
198 ($ty:ty) => { <$ty as Reflection>::name() }
199}
200
201macro_rules! name_ {
202 ($ty:ty) => { <$ty as Reflection>::name().unwrap_or( String::from( "_" )) }
203}
204
205macro_rules! expander {
206 ($ty:ty) => { Some( <$ty as Reflection>::members )}
207}
208
209impl Reflection for bool { fn ty() -> Type { Type::Bool } fn schema( id: Id ) -> Schema { terminal( id, Type::Bool )}}
210impl Reflection for i8 { fn ty() -> Type { Type::I8 } fn schema( id: Id ) -> Schema { terminal( id, Type::I8 )}}
211impl Reflection for u8 { fn ty() -> Type { Type::U8 } fn schema( id: Id ) -> Schema { terminal( id, Type::U8 )}}
212impl Reflection for i16 { fn ty() -> Type { Type::I16 } fn schema( id: Id ) -> Schema { terminal( id, Type::I16 )}}
213impl Reflection for u16 { fn ty() -> Type { Type::U16 } fn schema( id: Id ) -> Schema { terminal( id, Type::U16 )}}
214impl Reflection for i32 { fn ty() -> Type { Type::I32 } fn schema( id: Id ) -> Schema { terminal( id, Type::I32 )}}
215impl Reflection for u32 { fn ty() -> Type { Type::U32 } fn schema( id: Id ) -> Schema { terminal( id, Type::U32 )}}
216impl Reflection for i64 { fn ty() -> Type { Type::I64 } fn schema( id: Id ) -> Schema { terminal( id, Type::I64 )}}
217impl Reflection for u64 { fn ty() -> Type { Type::U64 } fn schema( id: Id ) -> Schema { terminal( id, Type::U64 )}}
218impl Reflection for i128 { fn ty() -> Type { Type::I128 } fn schema( id: Id ) -> Schema { terminal( id, Type::I128 )}}
219impl Reflection for u128 { fn ty() -> Type { Type::U128 } fn schema( id: Id ) -> Schema { terminal( id, Type::U128 )}}
220impl Reflection for f32 { fn ty() -> Type { Type::F32 } fn schema( id: Id ) -> Schema { terminal( id, Type::F32 )}}
221impl Reflection for f64 { fn ty() -> Type { Type::F64 } fn schema( id: Id ) -> Schema { terminal( id, Type::F64 )}}
222
223impl<T:Reflection> Reflection for std::ops::Range<T> {
224 fn ty() -> Type { Type::Range }
225 fn name() -> Name { Some( format!( "Range<{}>", name_!(T) ))}
226 fn schema( id: Id ) -> Schema { field( id, Type::Range, name!(Self), expander!(Self) )}
227 fn members() -> Schemas {
228 - field( "start", ty!(T), name!(T), expander!(T) )
229 - field( "end", ty!(T), name!(T), expander!(T) )
230 }
231}
232
233impl<'a> Reflection for &'a str { fn ty() -> Type { Type::RefStr } fn schema( id: Id ) -> Schema { terminal( id, Type::String )}}
234impl Reflection for String { fn ty() -> Type { Type::String } fn schema( id: Id ) -> Schema { terminal( id, Type::String )}}
235
236impl<T> Reflection for *const T where T: ?Sized + Reflection {
237 fn ty() -> Type { Type::CPtr }
238 fn name() -> Name { Some( format!( "*const {}", name_!(T) ))}
239 fn schema( id: Id ) -> Schema { field( id, Type::CPtr, name!(Self), expander!(Self) )}
240 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
241}
242
243impl<T> Reflection for *mut T where T: ?Sized + Reflection {
244 fn ty() -> Type { Type::Ptr }
245 fn name() -> Name { Some( format!( "*mut {}", name_!(T) ))}
246 fn schema( id: Id ) -> Schema { field( id, Type::Ptr, name!(Self), expander!(Self) )}
247 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
248}
249
250impl<T> Reflection for std::ptr::NonNull<T> where T: ?Sized + Reflection {
251 fn ty() -> Type { Type::NonNull }
252 fn name() -> Name { Some( format!( "NonNull<{}>", name_!(T) ))}
253 fn schema( id: Id ) -> Schema { field( id, Type::NonNull, name!(Self), expander!(Self) )}
254 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
255}
256
257impl<'a,T> Reflection for &'a T where T: 'a + ?Sized + Reflection {
258 fn ty() -> Type { Type::Ref }
259 fn name() -> Name { Some( format!( "&{}", name_!(T) ))}
260 fn schema( id: Id ) -> Schema { field( id, Type::Ref, name!(Self), expander!(Self) )}
261 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
262}
263
264impl<'a,T> Reflection for &'a mut T where T: 'a + ?Sized + Reflection {
265 fn ty() -> Type { Type::RefMut }
266 fn name() -> Name { Some( format!( "&mut {}", name_!(T) ))}
267 fn schema( id: Id ) -> Schema { field( id, Type::RefMut, name!(Self), expander!(Self) )}
268 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
269}
270
271impl<T> Reflection for Box<T> where T: ?Sized + Reflection {
272 fn ty() -> Type { Type::Box }
273 fn name() -> Name { Some( format!( "Box<{}>", name_!(T) ))}
274 fn schema( id: Id ) -> Schema { field( id, Type::Box, name!(Self), expander!(Self) )}
275 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
276}
277
278impl<T> Reflection for std::rc::Rc<T> where T: ?Sized + Reflection {
279 fn ty() -> Type { Type::Rc }
280 fn name() -> Name { Some( format!( "Rc<{}>", name_!(T) ))}
281 fn schema( id: Id ) -> Schema { field( id, Type::Rc, name!(Self), expander!(Self) )}
282 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
283}
284
285impl<T> Reflection for Vec<T> where T: Reflection {
286 fn ty() -> Type { Type::Vec }
287 fn name() -> Name { Some( format!( "Vec<{}>", name_!(T) ))}
288 fn schema( id: Id ) -> Schema { field( id, Type::Vec, name!(Self), expander!(Self) )}
289 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
290}
291
292impl<T> Reflection for Option<T> where T: Reflection {
293 fn ty() -> Type { Type::Enum }
294 fn name() -> Name { Some( format!( "Option<{}>", name_!(T) ))}
295 fn schema( id: Id ) -> Schema { field( id, Type::Option, name!(Self), expander!(Self) )}
296 fn members() -> Schemas {
297 -( variant( "None" ))
298 -( variant( "Some" ) / field( "0", ty!(T), name!(T), expander!(T) ))
299 }
300}
301
302impl<T,E> Reflection for Result<T,E> where T: Reflection, E: Reflection {
303 fn ty() -> Type { Type::Result }
304 fn name() -> Name { Some( format!( "Result<{},{}>", name_!(T), name_!(E) ))}
305 fn schema( id: Id ) -> Schema { field( id, Type::Result, name!(Self), expander!(Self) )}
306 fn members() -> Schemas {
307 -( variant( "Ok" ) / field( "_", ty!(T), name!(T), expander!(T) ))
308 -( variant( "Err" ) / field( "_", ty!(E), name!(E), expander!(E) ))
309 }
310}
311
312impl<T:Reflection> Reflection for std::collections::BTreeSet<T> {
313 fn ty() -> Type { Type::BTreeSet }
314 fn name() -> Name { Some( format!( "BTreeSet<{}>", name_!(T) ))}
315 fn schema( id: Id ) -> Schema { field( id, Type::BTreeSet, name!(Self), expander!(Self) )}
316 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
317}
318
319impl<T:Reflection> Reflection for std::collections::HashSet<T> {
320 fn ty() -> Type { Type::HashSet }
321 fn name() -> Name { Some( format!( "HashSet<{}>", name_!(T) ))}
322 fn schema( id: Id ) -> Schema { field( id, Type::HashSet, name!(Self), expander!(Self) )}
323 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
324}
325
326impl<K,V> Reflection for std::collections::BTreeMap<K,V> where K: Reflection, V: Reflection {
327 fn ty() -> Type { Type::BTreeMap }
328 fn name() -> Name { Some( format!( "BTreeMap<{},{}>", name_!(K), name_!(V) ))}
329 fn schema( id: Id ) -> Schema { field( id, Type::BTreeMap, name!(Self), expander!(Self) )}
330 fn members() -> Schemas {
331 - field( "name", ty!(K), name!(K), expander!(K) )
332 - field( "value", ty!(V), name!(V), expander!(V) )
333 }
334}
335
336impl<K,V> Reflection for std::collections::HashMap<K,V> where K: Reflection, V: Reflection {
337 fn ty() -> Type { Type::HashMap }
338 fn name() -> Name { Some( format!( "HashMap<{},{}>", name_!(K), name_!(V) ))}
339 fn schema( id: Id ) -> Schema { field( id, Type::HashMap, name!(Self), expander!(Self) )}
340 fn members() -> Schemas {
341 - field( "name", ty!(K), name!(K), expander!(K) )
342 - field( "value", ty!(V), name!(V), expander!(V) )
343 }
344}
345
346impl<T> Reflection for [T] where T: Reflection {
347 fn ty() -> Type { Type::Array }
348 fn name() -> Name { Some( format!( "[{}]", name_!(T) ))}
349 fn schema( id: Id ) -> Schema { field( id, Type::Array, name!(Self), expander!(Self) )}
350 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
351}
352
353macro_rules! array_impls {
354 ($($len:tt)+) => {
355 $(
356 impl<T> Reflection for [T;$len] where T: Reflection {
357 fn ty() -> Type { Type::Array }
358 fn name() -> Name { Some( format!( "[{}]", name_!(T) ))}
359 fn schema( id: Id ) -> Schema { field( id, Type::Array, name!(Self), expander!(Self) )}
360 fn members() -> Schemas { - field( "_", ty!(T), name!(T), expander!(T) )}
361 }
362 )+
363 }
364}
365
366array_impls!(
367 01 02 03 04 05 06 07 08
368 09 10 11 12 13 14 15 16
369 17 18 19 20 21 22 23 24
370 25 26 27 28 29 30 31 32
371);
372
373impl Reflection for () {
374 fn ty() -> Type { Type::Tuple }
375 fn name() -> Name { Some( format!( "()" ))}
376 fn schema( id: Id ) -> Schema { field( id, Type::Tuple, name!(Self), None )}
377}
378
379impl<T0> Reflection for (T0,)
380 where T0: Reflection,
381{
382 fn ty() -> Type { Type::Tuple }
383 fn name() -> Name { Some( format!( "({},)", name_!(T0) ))}
384 fn schema( id: Id ) -> Schema { field( id, Type::Tuple, name!(Self), expander!(Self) )}
385 fn members() -> Schemas { - field( "0", ty!(T0), name!(T0), expander!(T0) )}
386}
387
388impl<T0,T1> Reflection for (T0,T1)
389 where T0: Reflection, T1: Reflection,
390{
391 fn ty() -> Type { Type::Tuple }
392 fn name() -> Name { Some( format!( "({},{})", name_!(T0), name_!(T1) ))}
393 fn schema( id: Id ) -> Schema { field( id, Type::Tuple, name!(Self), expander!(Self) )}
394 fn members() -> Schemas {
395 - field( "0", ty!(T0), name!(T0), expander!(T0) )
396 - field( "1", ty!(T1), name!(T1), expander!(T1) )
397 }
398}
399
400impl<T0,T1,T2> Reflection for (T0,T1,T2)
401 where T0: Reflection, T1: Reflection, T2: Reflection
402{
403 fn ty() -> Type { Type::Tuple }
404 fn name() -> Name { Some( format!( "({},{},{})", name_!(T0), name_!(T1), name_!(T2) ))}
405 fn schema( id: Id ) -> Schema { field( id, Type::Tuple, name!(Self), expander!(Self) )}
406 fn members() -> Schemas {
407 - field( "0", ty!(T0), name!(T0), expander!(T0) )
408 - field( "1", ty!(T1), name!(T1), expander!(T1) )
409 - field( "2", ty!(T2), name!(T2), expander!(T2) )
410 }
411}
412
413impl<T0,T1,T2,T3> Reflection for (T0,T1,T2,T3)
414 where T0: Reflection, T1: Reflection, T2: Reflection, T3: Reflection
415{
416 fn ty() -> Type { Type::Tuple }
417 fn name() -> Name { Some( format!( "({},{},{},{})", name_!(T0), name_!(T1), name_!(T2), name_!(T3) ))}
418 fn schema( id: Id ) -> Schema { field( id, Type::Tuple, name!(Self), expander!(Self) )}
419 fn members() -> Schemas {
420 - field( "0", ty!(T0), name!(T0), expander!(T0) )
421 - field( "1", ty!(T1), name!(T1), expander!(T1) )
422 - field( "2", ty!(T2), name!(T2), expander!(T2) )
423 - field( "3", ty!(T3), name!(T3), expander!(T3) )
424 }
425}
426
427impl<T0,T1,T2,T3,T4> Reflection for (T0,T1,T2,T3,T4)
428 where T0: Reflection, T1: Reflection, T2: Reflection, T3: Reflection, T4: Reflection
429{
430 fn ty() -> Type { Type::Tuple }
431 fn name() -> Name { Some( format!( "({},{},{},{},{})", name_!(T0), name_!(T1), name_!(T2), name_!(T3), name_!(T4) ))}
432 fn schema( id: Id ) -> Schema { field( id, Type::Tuple, name!(Self), expander!(Self) )}
433 fn members() -> Schemas {
434 - field( "0", ty!(T0), name!(T0), expander!(T0) )
435 - field( "1", ty!(T1), name!(T1), expander!(T1) )
436 - field( "2", ty!(T2), name!(T2), expander!(T2) )
437 - field( "3", ty!(T3), name!(T3), expander!(T3) )
438 - field( "4", ty!(T4), name!(T4), expander!(T4) )
439 }
440}
441
442impl<T0,T1,T2,T3,T4,T5> Reflection for (T0,T1,T2,T3,T4,T5)
443 where T0: Reflection, T1: Reflection, T2: Reflection, T3: Reflection, T4: Reflection, T5: Reflection
444{
445 fn ty() -> Type { Type::Tuple }
446 fn name() -> Name { Some( format!( "({},{},{},{},{},{})", name_!(T0), name_!(T1), name_!(T2), name_!(T3), name_!(T4), name_!(T5) ))}
447 fn schema( id: Id ) -> Schema { field( id, Type::Tuple, name!(Self), expander!(Self) )}
448 fn members() -> Schemas {
449 - field( "0", ty!(T0), name!(T0), expander!(T0) )
450 - field( "1", ty!(T1), name!(T1), expander!(T1) )
451 - field( "2", ty!(T2), name!(T2), expander!(T2) )
452 - field( "3", ty!(T3), name!(T3), expander!(T3) )
453 - field( "4", ty!(T4), name!(T4), expander!(T4) )
454 - field( "5", ty!(T5), name!(T5), expander!(T5) )
455 }
456}