1 /**
2  *
3  * /home/tomas/workspace/mqtt-d/source/mqttd/traits.d
4  *
5  * Author:
6  * Tomáš Chaloupka <chalucha@gmail.com>
7  *
8  * Copyright (c) 2015 Tomáš Chaloupka
9  *
10  * Boost Software License 1.0 (BSL-1.0)
11  *
12  * Permission is hereby granted, free of charge, to any person or organization obtaining a copy
13  * of the software and accompanying documentation covered by this license (the "Software") to use,
14  * reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative
15  * works of the Software, and to permit third-parties to whom the Software is furnished to do so,
16  * all subject to the following:
17  *
18  * The copyright notices in the Software and this entire statement, including the above license
19  * grant, this restriction and the following disclaimer, must be included in all copies of the Software,
20  * in whole or in part, and all derivative works of the Software, unless such copies or derivative works
21  * are solely in the form of machine-executable object code generated by a source language processor.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
24  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25  * PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE
26  * DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT,
27  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  * OTHER DEALINGS IN THE SOFTWARE.
29  */
30 module mqttd.traits;
31 
32 import std.range;
33 import std.traits : isDynamicArray, isIntegral;
34 
35 import mqttd.messages;
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 packed can be deserialized from
62 enum bool canDeserializeFrom(R) = isInputRange!R && isIntegral!(ElementType!R) && !isInfinite!R;
63 
64 /// Range type Mqtt packed 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; }));
67 
68 enum bool isCondition(C) = is(C : Condition!C, alias C);