1 module libs.marshal.xml_text_marshaller; 2 3 import libs.marshal.text_marshaller, libs.marshal.marshaller; 4 import std.conv, std.string, std.traits; 5 import std.stdio; 6 7 alias Marshaller!(XmlMarshallerStrategy, TextMarshallerStorageStrategy) XmlTextMarshaller; 8 9 package class XmlMarshallerStrategy(StorageStrategy) : IMarshalStrategy 10 { 11 mixin MarshalMixinTemplate!(StorageStrategy); 12 13 void BeginDocumentMarshal(string name) 14 { 15 //m_storer.AddLine(`<?xml version="1.0" encoding="UTF-8"?>`); 16 } 17 18 void EndDocumentMarshal(string name) 19 { 20 } 21 22 void BeginObjectMarshal(T)(T val, string name) 23 { 24 m_storer.AddLine(format("<%s>", name)); 25 m_storer.IncrementIndentation(); 26 } 27 28 void EndObjectMarshal(T)(T val, string name) 29 { 30 m_storer.DecrementIndentation(); 31 m_storer.AddLine(format("</%s>", name)); 32 } 33 34 void BeginArrayMarshal(T)(T val, string name) 35 { 36 BeginObjectMarshal(val, name); 37 } 38 39 void EndArrayMarshal(T)(T val, string name) 40 { 41 EndObjectMarshal(val, name); 42 } 43 44 void MarshalSingleVar(T)(T val, string name) 45 { 46 m_storer.AddLine(format("<%s>%s</%s>", name, val, name)); 47 } 48 49 void MarshalEnum(T)(T val, string name) 50 { 51 MarshalSingleVar(val, name); 52 } 53 54 void MarshalUnion(T)(T val, string name) 55 { 56 MarshalSingleVar(val, name); 57 } 58 } 59 60 unittest { 61 //Integers 62 XmlTextMarshaller xml_marshaller = new XmlTextMarshaller; 63 xml_marshaller.Marshal(42, "meaning of life"); 64 assert(xml_marshaller.ToString() == "<meaning of life>42</meaning of life>\r\n"); 65 66 //Strings 67 xml_marshaller = new XmlTextMarshaller; 68 xml_marshaller.Marshal("a string", "name"); 69 assert(xml_marshaller.ToString() == "<name>a string</name>\r\n"); 70 71 //Enums 72 enum MyEnum 73 { 74 a = 10, 75 b, 76 c 77 } 78 MyEnum myenum; 79 xml_marshaller = new XmlTextMarshaller; 80 xml_marshaller.Marshal(myenum, "myenum"); 81 assert(xml_marshaller.ToString() == "<myenum>a</myenum>\r\n"); 82 83 //Arrays 84 xml_marshaller = new XmlTextMarshaller; 85 int[] ary = [1, 2, 3, 44, 5]; 86 xml_marshaller.Marshal(ary, "ary"); 87 assert(xml_marshaller.ToString() == "<ary>\r\n" ~ 88 "\t<0>1</0>\r\n" ~ 89 "\t<1>2</1>\r\n" ~ 90 "\t<2>3</2>\r\n" ~ 91 "\t<3>44</3>\r\n" ~ 92 "\t<4>5</4>\r\n" ~ 93 "</ary>\r\n"); 94 95 //Structs 96 xml_marshaller = new XmlTextMarshaller; 97 static struct A 98 { 99 int x = 10; 100 float y = 11.2; 101 string z = "test string"; 102 } 103 A a; 104 xml_marshaller.Marshal(a, "a"); 105 //writeln(xml_marshaller.ToString()); 106 assert(xml_marshaller.ToString() == "<a>\r\n" ~ 107 "\t<x>10</x>\r\n" ~ 108 "\t<y>11.2</y>\r\n" ~ 109 "\t<z>test string</z>\r\n" ~ 110 "</a>\r\n"); 111 112 //Nested Structs 113 xml_marshaller = new XmlTextMarshaller; 114 static struct B 115 { 116 int i1 = 1024; 117 float f1 = 22.2; 118 A a; 119 } 120 B b; 121 xml_marshaller.Marshal(b, "b"); 122 //writeln(xml_marshaller.ToString()); 123 assert(xml_marshaller.ToString() == "<b>\r\n" ~ 124 "\t<i1>1024</i1>\r\n" ~ 125 "\t<f1>22.2</f1>\r\n" ~ 126 "\t<a>\r\n" ~ 127 "\t\t<x>10</x>\r\n" ~ 128 "\t\t<y>11.2</y>\r\n" ~ 129 "\t\t<z>test string</z>\r\n" ~ 130 "\t</a>\r\n" ~ 131 "</b>\r\n"); 132 133 //Self Defined Marshal Function 134 xml_marshaller = new XmlTextMarshaller; 135 static struct C 136 { 137 void Marshal(MarshalStrategy : XmlMarshallerStrategy!StorageStrategy, StorageStrategy : TextMarshallerStorageStrategy)(StorageStrategy storer, string name) 138 { 139 storer.AddText(format("%s: inner", name)); 140 } 141 } 142 C c; 143 xml_marshaller.Marshal(c, "cab"); 144 assert(xml_marshaller.ToString() == "cab: inner"); 145 146 //Self Defined Begin and End Marshal Functions 147 xml_marshaller = new XmlTextMarshaller; 148 static struct D 149 { 150 int x = 1; 151 void BeginObjectMarshal(MarshalStrategy : XmlMarshallerStrategy!StorageStrategy, StorageStrategy : TextMarshallerStorageStrategy)(StorageStrategy storer, string name) 152 { 153 storer.AddText(format("%s: start, ", name)); 154 } 155 156 void EndObjectMarshal(MarshalStrategy : XmlMarshallerStrategy!StorageStrategy, StorageStrategy : TextMarshallerStorageStrategy)(StorageStrategy storer, string name) 157 { 158 storer.AddText(format("%s: end", name)); 159 } 160 } 161 D d; 162 xml_marshaller.Marshal(d, "cab"); 163 // writeln(xml_marshaller.ToString()); 164 assert(xml_marshaller.ToString() == "cab: start, <x>1</x>\r\ncab: end"); 165 166 //Self Defined Begin/End for array... 167 //Doesn't work. Need Begin and End Array Marshal to be visible to marshaller.d? 168 xml_marshaller = new XmlTextMarshaller; 169 170 struct E 171 { 172 int x = 2; 173 } 174 175 @property void BeginArrayMarshal 176 (MarshalStrategy : XmlMarshallerStrategy!StorageStrategy, 177 StorageStrategy : TextMarshallerStorageStrategy) 178 (E[] ary, StorageStrategy storer, string name) 179 { 180 storer.AddText(format("start %s\r\n", name)); 181 } 182 183 @property void EndArrayMarshal 184 (MarshalStrategy : XmlMarshallerStrategy!StorageStrategy, 185 StorageStrategy : TextMarshallerStorageStrategy) 186 (E[] ary, StorageStrategy storer, string name) 187 { 188 storer.AddText(format("end %s\r\n", name)); 189 } 190 191 E[] e_ary = [E(), E(), E()]; 192 xml_marshaller.Marshal(e_ary, "e_ary"); 193 //writeln(xml_marshaller.ToString()); // Doesn't print what we expect..! 194 //assert( xml_marshaller.ToString() == "start e_ary\r\n" ~ 195 // "<0>..............\r\n"); 196 }