1 module ddbus.attributes; 2 3 import std.meta : allSatisfy; 4 import std.traits : getUDAs; 5 import std.typecons : BitFlags, Flag; 6 7 /++ 8 Flags for use with dbusMarshaling UDA 9 10 Default is to include public fields only 11 +/ 12 enum MarshalingFlag : ubyte { 13 /++ 14 Automatically include private fields 15 +/ 16 includePrivateFields = 1 << 0, 17 18 /++ 19 Only include fields with explicit `@Yes.DBusMarshal`. This overrides any 20 `include` flags. 21 +/ 22 manualOnly = 1 << 7 23 } 24 25 /++ 26 UDA for specifying DBus marshaling options on structs 27 +/ 28 auto dbusMarshaling(Args)(Args args...) 29 if (allSatisfy!(isMarshalingFlag, Args)) { 30 return BitFlags!MarshalingFlag(args); 31 } 32 33 package(ddbus) template isAllowedField(alias field) { 34 private enum flags = marshalingFlags!(__traits(parent, field)); 35 private alias getUDAs!(field, Flag!"DBusMarshal") UDAs; 36 37 static if (UDAs.length != 0) { 38 static assert(UDAs.length == 1, 39 "Only one UDA of type Flag!\"DBusMarshal\" allowed on struct field."); 40 41 static assert(is(typeof(UDAs[0]) == Flag!"DBusMarshal"), 42 "Did you intend to add UDA Yes.DBusMarshal or No.DBusMarshal?"); 43 44 enum isAllowedField = cast(bool) UDAs[0]; 45 } else static if (!(flags & MarshalingFlag.manualOnly)) { 46 static if (__traits(getProtection, field) == "public") { 47 enum isAllowedField = true; 48 } else static if (cast(bool)(flags & MarshalingFlag.includePrivateFields)) { 49 enum isAllowedField = true; 50 } else { 51 enum isAllowedField = false; 52 } 53 } else { 54 enum isAllowedField = false; 55 } 56 } 57 58 private template isMarshalingFlag(T) { 59 enum isMarshalingFlag = is(T == MarshalingFlag); 60 } 61 62 private template marshalingFlags(S) 63 if (is(S == struct)) { 64 private alias getUDAs!(S, BitFlags!MarshalingFlag) UDAs; 65 66 static if (UDAs.length == 0) { 67 enum marshalingFlags = BitFlags!MarshalingFlag.init; 68 } else { 69 static assert(UDAs.length == 1, "Only one @dbusMarshaling UDA allowed on type."); 70 static assert(is(typeof(UDAs[0]) == BitFlags!MarshalingFlag), 71 "Huh? Did you intend to use @dbusMarshaling UDA?"); 72 enum marshalingFlags = UDAs[0]; 73 } 74 }