1 module libs.marshal.human_readable_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) HumanReadableTextMarshaller;
8 
9 package class XmlMarshallerStrategy(StorageStrategy) : IMarshalStrategy
10 {
11 	mixin MarshalMixinTemplate!(StorageStrategy);
12 	
13 	void BeginDocumentMarshal(string name)
14 	{
15 		m_storer.SetIndentationString(" ");
16 	}
17 	
18 	void EndDocumentMarshal(string name)
19 	{
20 		
21 	}
22 	
23 	void BeginObjectMarshal(T)(T val, string name)
24 	{
25 		m_storer.AddLine(format("%s:", name));
26 		m_storer.IncreaseIndentation(name.length + 2);
27 	}
28 	
29 	void EndObjectMarshal(T)(T val, string name)
30 	{
31 		m_storer.UndoLastIndentation();
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", name, val));
47 	}
48 		
49 	void MarshalEnum(T)(T val, string name)
50 	{
51 		m_storer.AddLine(format("%s: \"%s\" (%s)", name, to!string(val), to!(OriginalType!T)(val)));
52 	}
53 		
54 	void MarshalUnion(T)(T val, string name)
55 	{
56 		MarshalSingleVar(val, name);
57 	}
58 }
59 
60 unittest {
61 	//Integers
62 	HumanReadableTextMarshaller human_readable_marshaller = new HumanReadableTextMarshaller;
63 	human_readable_marshaller.Marshal(42, "meaning of life");
64 	assert(human_readable_marshaller.ToString() == "meaning of life: 42\r\n");
65 	
66 	//Strings
67 	human_readable_marshaller = new HumanReadableTextMarshaller;
68 	human_readable_marshaller.Marshal("a string", "name");
69 	assert(human_readable_marshaller.ToString() == "name: a string\r\n");
70 
71 	//Enums
72 	enum MyEnum
73 	{
74 		a = 10,
75 		b,
76 		c
77 	}
78 	MyEnum myenum;
79 	human_readable_marshaller = new HumanReadableTextMarshaller;
80 	human_readable_marshaller.Marshal(myenum, "myenum");
81 	assert(human_readable_marshaller.ToString() == "myenum: \"a\" (10)\r\n");
82 
83 	//Arrays
84 	human_readable_marshaller = new HumanReadableTextMarshaller;
85 	int[] ary = [1, 2, 3, 44, 5];
86 	human_readable_marshaller.Marshal(ary, "ary");
87 	//writeln(human_readable_marshaller.ToString());
88 	assert(human_readable_marshaller.ToString() == "ary:\r\n" ~ 
89 												   "     0: 1\r\n" ~ 
90 												   "     1: 2\r\n" ~
91 												   "     2: 3\r\n" ~
92 												   "     3: 44\r\n" ~
93 												   "     4: 5\r\n");
94 	
95 	//Structs
96 	human_readable_marshaller = new HumanReadableTextMarshaller;
97 	static struct A
98 	{
99 		int x = 10;
100 		float y = 11.2;
101 		string z = "test string";
102 	}
103 	A a;
104 	human_readable_marshaller.Marshal(a, "a");
105 	//writeln(human_readable_marshaller.ToString());
106 	assert(human_readable_marshaller.ToString() == "a:\r\n" ~ 
107 												   "   x: 10\r\n" ~
108 												   "   y: 11.2\r\n" ~
109 												   "   z: test string\r\n");
110 	
111 	//Nested Structs
112 	human_readable_marshaller = new HumanReadableTextMarshaller;
113 	static struct B
114 	{
115 		A a;
116 		int i1 = 1024;
117 		float f1 = 22.2;
118 	}
119 	B b;
120 	human_readable_marshaller.Marshal(b, "b");
121 	//writeln(human_readable_marshaller.ToString());
122 	assert(human_readable_marshaller.ToString() == "b:\r\n" ~
123 												   "   a:\r\n" ~
124 												   "      x: 10\r\n" ~
125 												   "      y: 11.2\r\n" ~
126 												   "      z: test string\r\n" ~
127 												   "   i1: 1024\r\n" ~
128 												   "   f1: 22.2\r\n");
129 	
130 	//Self Defined Marshal Function
131 	human_readable_marshaller = new HumanReadableTextMarshaller;
132 	static struct C
133 	{
134 		void Marshal(MarshalStrategy : XmlMarshallerStrategy!StorageStrategy, StorageStrategy : TextMarshallerStorageStrategy)(StorageStrategy storer, string name)
135 		{
136 			storer.AddText(format("%s: inner", name));
137 		}
138 	}
139 	C c;
140 	human_readable_marshaller.Marshal(c, "cab");
141 	assert(human_readable_marshaller.ToString() == "cab: inner");
142 }