1 module osc.typetag; 2 3 import std.algorithm; 4 import std.array; 5 import std.conv; 6 import std.datetime; 7 8 9 alias TypeTagString = string; 10 11 12 /// Type tag for each supported tags. 13 /// 14 enum TypeTag : char 15 { 16 Integer = 'i', 17 Float = 'f', 18 String = 's', 19 Blob = 'b', 20 True = 'T', 21 False = 'F', 22 Null = 'N', 23 Impulse = 'I', 24 TimeTag = 't', 25 } 26 27 28 /// Constructs a TypeTag string using a list of types. 29 /// 30 TypeTagString build( T... )( ) 31 { 32 TypeTagString res; 33 34 foreach( t; T ) 35 { 36 static if( is(t == int) ) 37 res = res.add!int; 38 else static if( is(t == float) ) 39 res = res.add!float; 40 else static if( is(t == string) ) 41 res = res.add!string; 42 else static if( is(t == ubyte[]) ) 43 res = res.add!(ubyte[]); 44 else static if( is(typeof(t) == typeof(null)) ) 45 res = res.addNull; 46 else static if( is(typeof(t) == bool) ) 47 res = res.add!bool( t ); 48 else static if( is(typeof(t) == char) && t is 'I' ) 49 res = res.addImpulse; 50 else static if( is(t == SysTime) ) 51 res = res.add!SysTime; 52 else 53 static assert( 0, "Invalid type." ); 54 } 55 56 return res; 57 } 58 59 60 /// Adds an integer type tag. 61 /// 62 TypeTagString add(T:int)(TypeTagString str) 63 { 64 return str ~ TypeTag.Integer; 65 } 66 67 /// Adds a float type tag. 68 /// 69 TypeTagString add(T:float)(TypeTagString str) 70 { 71 return str ~ TypeTag.Float; 72 } 73 74 /// Adds a string type tag. 75 /// 76 TypeTagString add(T:string)(TypeTagString str) 77 { 78 return str ~ TypeTag.String; 79 } 80 81 /// Adds a blob type tag. 82 /// 83 TypeTagString add(T:ubyte[])(TypeTagString str) 84 { 85 return str ~ TypeTag.Blob; 86 } 87 88 /// Adds a bool type tag. 89 /// 90 TypeTagString add(T:bool)(TypeTagString str, T v) 91 { 92 if( v ) 93 return str ~ TypeTag.True; 94 else 95 return str ~ TypeTag.False; 96 } 97 98 /// Adds a null type tag. 99 /// 100 TypeTagString addNull(TypeTagString str) 101 { 102 return str ~ TypeTag.Null; 103 } 104 105 /// Adds an impulse type tag. 106 /// 107 TypeTagString addImpulse(TypeTagString str) 108 { 109 return str ~ TypeTag.Impulse; 110 } 111 112 /// Adds a timetag type tag. 113 /// 114 TypeTagString add(T:SysTime)(TypeTagString str) 115 { 116 return str ~ TypeTag.TimeTag; 117 } 118 119 120 121 unittest 122 { 123 TypeTagString str; 124 125 str = str.add!int 126 .add!float 127 .add!string 128 .add!(ubyte[]) 129 .add!bool(true) 130 .add!bool(false) 131 .addNull 132 .addImpulse 133 .add!SysTime; 134 135 assert( str == "ifsbTFNIt" ); 136 } 137 138 unittest 139 { 140 TypeTagString str = build!( int, float, string, ubyte[], true, false, null, 141 'I', SysTime)(); 142 143 assert( str == "ifsbTFNIt" ); 144 }