1 
2 module witchcraft.impl.inspect;
3 
4 import witchcraft;
5 
6 import std.meta;
7 
8 /++
9  + Inspects a type given by template argument using the `metaof` property if
10  + the type defines one. Otherwise, a `null` is returned.
11  +
12  + If aggressive version of `Witchcraft` is used, this method behaves
13  + differently and returns a generic aggressive meta type.
14  +
15  + Returns:
16  +   The meta type of the type given by a parameter.
17  ++/
18 @property
19 Type inspect(TList...)()
20 if(TList.length == 1)
21 {
22     alias T = TList[0];
23 
24     static if(__traits(hasMember, T, "metaof"))
25     {
26         return T.metaof;
27     }
28     else
29     {
30         version(aggressive)
31         {
32             static if(is(T == class))
33             {
34                 return new ClassImpl!T;
35             }
36             else static if(is(T == struct))
37             {
38                 return new StructImpl!T;
39             }
40             else static if(is(T == interface))
41             {
42                 return new InterfaceTypeImpl!T;
43             }
44             else static if(!is(T))
45             {
46                 return new ModuleImpl!T;
47             }
48             else
49             {
50                 return null;
51             }
52         }
53         else
54         {
55             return null;
56         }
57     }
58 }
59 
60 /++
61  + Inspects a value, using the `getMetaType` method if present. Otherwise,
62  + the value's type is inspected by the generic `inspect` function type.
63  +
64  + Params:
65  +   value = The parameter value to be inspected.
66  +
67  + Returns:
68  +   The meta type of the value given by a parameter.
69  +
70  + See_Also:
71  +   inspect()
72  ++/
73 @property
74 Type inspect(T)(T value)
75 {
76     static if(__traits(hasMember, T, "getMetaType"))
77     {
78         return value ? value.getMetaType : null;
79     }
80     else
81     {
82         return inspect!T;
83     }
84 }