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 }