1 /**
2  * Helper checks for template arguments
3  *
4  * Author:
5  * Tomáš Chaloupka <chalucha@gmail.com>
6  *
7  * License:
8  * Boost Software License 1.0 (BSL-1.0)
9  *
10  * Permission is hereby granted, free of charge, to any person or organization obtaining a copy
11  * of the software and accompanying documentation covered by this license (the "Software") to use,
12  * reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative
13  * works of the Software, and to permit third-parties to whom the Software is furnished to do so,
14  * all subject to the following:
15  *
16  * The copyright notices in the Software and this entire statement, including the above license
17  * grant, this restriction and the following disclaimer, must be included in all copies of the Software,
18  * in whole or in part, and all derivative works of the Software, unless such copies or derivative works
19  * are solely in the form of machine-executable object code generated by a source language processor.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
22  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
23  * PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE
24  * DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT,
25  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26  * OTHER DEALINGS IN THE SOFTWARE.
27  */
28 module mqttd.traits;
29 
30 import std.range;
31 import std.traits : isDynamicArray, isIntegral;
32 
33 import mqttd.messages;
34 
35 @safe:
36 
37 /// Is one of Mqtt packet types?
38 enum bool isMqttPacket(T) = is(T == Connect) || is(T == ConnAck)
39 	|| is(T == Publish) || is(T == PubAck) || is(T == PubRec) || is(T == PubRel) || is(T == PubComp)
40 		|| is(T == Subscribe) || is(T == SubAck)
41 		|| is(T == Unsubscribe) || is(T == UnsubAck)
42 		|| is(T == PingReq) || is(T == PingResp)
43 		|| is(T == Disconnect);
44 
45 enum bool canReadBase(T) = is(T:ubyte) || is(T:ushort) || is(T:string)
46 	|| is(T == FixedHeader) || is(T == ConnectFlags) || is(T == ConnAckFlags) || is(T == Topic);
47 
48 /// Can T be read by Reader?
49 enum bool canRead(T) = canReadBase!T || (isDynamicArray!T && canReadBase!(ElementType!T));
50 
51 /// Can T be written by Writer?
52 enum bool canWrite(T) = canRead!T;
53 
54 /// Has Fixed Header member
55 enum bool hasFixedHeader(T) = is(typeof(()
56 		{
57 			auto obj = T.init;
58 			FixedHeader h = obj.header;
59 		}));
60 
61 /// Range type Mqtt packet can be deserialized from
62 enum bool canDeserializeFrom(R) = isInputRange!R && isIntegral!(ElementType!R) && !isInfinite!R;
63 
64 /// Range type Mqtt packet can be serialized to
65 enum bool canSerializeTo(R) = isOutputRange!(R, ubyte) &&
66 	is(typeof(() { auto r = R(); r.clear(); const(ubyte)[] d = r.data; }));