1 
2 module witchcraft.attributes;
3 
4 import witchcraft;
5 
6 import std.conv;
7 import std.variant;
8 
9 /++
10  + Represents a single attribute attached to some element.
11  ++/
12 abstract class Attribute
13 {
14     /++
15      + Reads the runtime value of the attribute if it caqn produce one. The
16      + result is returned as a `Variant` object.
17      +
18      + Returns:
19      +   A `Variant` that constains the runtime value of the attribute.
20      ++/
21     @property
22     abstract Variant get() const;
23 
24     /++
25      + Ditto, but also accepts a template parameter which the result is
26      + converted to (if the conversion is possible).
27      +
28      + Params:
29      +   T = The conversion type.
30      +
31      + Returns:
32      +   The converted attribute value.
33      ++/
34     @property
35     T get(T)() const
36     {
37         return this.get.get!T;
38     }
39 
40     @property
41     abstract const(Type) getAttributeType() const;
42 
43     @property
44     abstract const(TypeInfo) getAttributeTypeInfo() const;
45 
46     /++
47      + Checks if this attribute is expression. Any attribute that can produce
48      + a value at runtime is considered an expression attribute.
49      +
50      + Returns:
51      +   `true` if the attribute produces a runtime value.
52      +
53      + See_Also:
54      +   isType
55      ++/
56     @property
57     abstract bool isExpression() const;
58 
59     /++
60      + Checks if this attribute is a type (or some other non-expression).
61      +
62      + Returns:
63      +   `true` if the attribute does not produce a runtime value.
64      ++/
65     @property
66     abstract bool isType() const;
67 
68     override string toString() const
69     {
70         if(isExpression)
71         {
72             return "@(" ~ get.text ~ ")";
73         }
74         else
75         {
76             return "@(" ~ getAttributeType.text ~ ")";
77         }
78     }
79 }