1 module text.xml.Xml;
2 
3 import std.typecons;
4 
5 // UDA for text.xml.Encode/Decode
6 struct Xml
7 {
8     // free function so both @(Xml.Attribute) and @(Xml.Attribute("name")) work
9     // (you can't pass a type to an UDA, but you can pass a function.)
10     public static AttributeName Attribute(string name)
11     {
12         return AttributeName(name);
13     }
14 
15     public static ElementName Element(string name)
16     {
17         return ElementName(name);
18     }
19 
20     public static struct Text
21     {
22     }
23 
24     public alias attributeName(attributes...) = attributeNameImpl!(Attribute, AttributeName, attributes);
25 
26     public alias elementName(attributes...) = attributeNameImpl!(Element, ElementName, attributes);
27 
28     deprecated("Node is now Element")
29     alias Node = Element;
30 
31     public static struct Decode(alias DecodeFunction_)
32     {
33         alias DecodeFunction = DecodeFunction_;
34     }
35 
36     public static struct Encode(alias EncodeFunction_)
37     {
38         alias EncodeFunction = EncodeFunction_;
39     }
40 
41     private static struct AttributeName
42     {
43         string name;
44     }
45 
46     private static struct ElementName
47     {
48         string name;
49     }
50 }
51 
52 private static Nullable!string attributeNameImpl(alias function_, alias type, attributes...)(string name)
53 {
54     assert(__ctfe);
55 
56     import meta.udaIndex : udaIndex;
57 
58     alias functionIndex = udaIndex!function_;
59     alias structIndex = udaIndex!type;
60 
61     static if (functionIndex!attributes != -1)
62     {
63         return Nullable!string(name);
64     }
65     else static if (structIndex!attributes != -1)
66     {
67         return Nullable!string(attributes[structIndex!attributes].name);
68     }
69     else
70     {
71         return Nullable!string();
72     }
73 }