1 module libs.marshal.marshaller; 2 3 import std.traits; 4 import std.stdio; 5 import std.conv; 6 7 package interface IMarshalStrategy 8 { 9 void BeginDocumentMarshal(string name); 10 void EndDocumentMarshal(string name); 11 12 void BeginObjectMarshal(T)(T val, string name); 13 void EndObjectMarshal(T)(T val, string name); 14 15 void BeginArrayMarshal(T)(T val, string name); 16 void EndArrayMarshal(T)(T val, string name); 17 18 void MarshalClassOrStruct(T)(T val, string name); 19 void MarshalArray(T)(StorageStrategy storer, T val, string name); 20 void MarshalSingleVar(T)(T val, string name); 21 void MarshalEnum(T)(T val, string name); 22 void MarshalUnion(T)(T val, string name); 23 } 24 25 package class Marshaller(alias InMarshalStrategy, StorageStrategy) 26 { 27 public: 28 alias InMarshalStrategy!(StorageStrategy) MarshalStrategy; 29 30 final string ToString() 31 { 32 return to!string(m_storer.GetBuffer().idup); 33 } 34 35 final auto GetBuffer() 36 { 37 return m_storer.GetBuffer().idup; 38 } 39 40 void Marshal(T)(T val, string name) 41 { 42 m_marshaller.Marshal(val, name); 43 } 44 45 this() 46 { 47 m_storer = new StorageStrategy; 48 m_marshaller = new MarshalStrategy(m_storer); 49 m_marshaller.BeginDocumentMarshal(""); 50 } 51 52 private: 53 StorageStrategy m_storer; 54 MarshalStrategy m_marshaller; 55 } 56 57 mixin template MarshalMixinTemplate(StorageStrategy) 58 { 59 void MarshalClassOrStruct(T)(T val, string name) 60 { 61 static if (__traits(hasMember, T, "BeginObjectMarshal") && __traits(hasMember, T, "EndObjectMarshal") 62 && (isSomeFunction!(T.BeginObjectMarshal!(typeof(this), StorageStrategy)) 63 && (is(TemplateArgsOf!(T.BeginObjectMarshal!(typeof(this), StorageStrategy))[0] == typeof(this)) 64 && is(TemplateArgsOf!(T.BeginObjectMarshal!(typeof(this), StorageStrategy))[1] == StorageStrategy))) 65 && (isSomeFunction!(T.EndObjectMarshal!(typeof(this), StorageStrategy)) 66 && (is(TemplateArgsOf!(T.EndObjectMarshal!(typeof(this), StorageStrategy))[0] == typeof(this)) 67 && is(TemplateArgsOf!(T.EndObjectMarshal!(typeof(this), StorageStrategy))[1] == StorageStrategy)))) 68 { 69 val.BeginObjectMarshal!(typeof(this), StorageStrategy)(m_storer, name); 70 foreach (item; __traits(allMembers, T)) 71 { 72 static if (__traits(compiles, Marshal(__traits(getMember, val, item), item)) 73 && !isSomeFunction!(typeof(__traits(getMember, val, item)))) 74 { 75 Marshal(__traits(getMember, val, item), item); 76 } 77 } 78 val.EndObjectMarshal!(typeof(this), StorageStrategy)(m_storer, name); 79 } 80 else 81 { 82 BeginObjectMarshal(val, name); 83 foreach (item; __traits(allMembers, T)) 84 { 85 static if (__traits(compiles, Marshal(__traits(getMember, val, item), item)) 86 && !isSomeFunction!(typeof(__traits(getMember, val, item)))) 87 { 88 Marshal(__traits(getMember, val, item), item); 89 } 90 } 91 EndObjectMarshal(val, name); 92 } 93 } 94 95 void MarshalArray(T)(T val, string name) 96 { 97 static if (__traits(hasMember, T, "BeginArrayMarshal") && __traits(hasMember, T, "EndArrayMarshal") 98 && (isSomeFunction!(T.BeginArrayMarshal!(typeof(this), StorageStrategy)) 99 && (is(TemplateArgsOf!(T.BeginArrayMarshal!(typeof(this), StorageStrategy))[0] == typeof(this)) 100 && is(TemplateArgsOf!(T.BeginArrayMarshal!(typeof(this), StorageStrategy))[1] == StorageStrategy))) 101 && (isSomeFunction!(T.EndArrayMarshal!(typeof(this), StorageStrategy)) 102 && (is(TemplateArgsOf!(T.EndArrayMarshal!(typeof(this), StorageStrategy))[0] == typeof(this)) 103 && is(TemplateArgsOf!(T.EndArrayMarshal!(typeof(this), StorageStrategy))[1] == StorageStrategy)))) 104 { 105 val.BeginArrayMarshal!(typeof(this), StorageStrategy)(storer, name); 106 foreach (i, item; val) 107 { 108 Marshal(item, to!string(i)); 109 } 110 val.EndArrayMarshal!(typeof(this), StorageStrategy)(storer, name); 111 } 112 else 113 { 114 BeginArrayMarshal(val, name); 115 foreach (i, item; val) 116 { 117 Marshal(item, to!string(i)); 118 } 119 EndArrayMarshal(val, name); 120 } 121 } 122 123 void Marshal(T)(T val, string name) 124 { 125 static if (__traits(hasMember, T, "Marshal") 126 && isSomeFunction!(T.Marshal!(typeof(this), StorageStrategy)) 127 && (is(TemplateArgsOf!(T.Marshal!(typeof(this), StorageStrategy))[0] == typeof(this)) 128 && is(TemplateArgsOf!(T.Marshal!(typeof(this), StorageStrategy))[1] == StorageStrategy))) 129 { 130 val.Marshal!(typeof(this), StorageStrategy)(m_storer, name); 131 } 132 else static if (is(T == struct) || is(T == class)) 133 { 134 MarshalClassOrStruct(val, name); 135 } 136 else static if (isArray!(T) && !isSomeString!(T)) 137 { 138 MarshalArray(val, name); 139 } 140 else static if (is(T == enum)) 141 { 142 MarshalEnum(val, name); 143 } 144 else static if (is(T == union)) 145 { 146 MarshalUnion(val, name); 147 } 148 else static if (__traits(isPOD, T)) 149 { 150 //Any other POD, we've already covered structs 151 MarshalSingleVar(val, name); 152 } 153 else 154 { 155 //do nothing... 156 } 157 } 158 159 private StorageStrategy m_storer; 160 161 package this(StorageStrategy storer) 162 { 163 this.m_storer = storer; 164 } 165 166 }