1 module google.protobuf.wrappers; 2 3 import std.json : JSONValue; 4 import google.protobuf; 5 6 struct WrappedValue(T, string messageTypeFullName_) 7 { 8 import std.typecons : Nullable; 9 10 enum messageTypeFullName = messageTypeFullName_; 11 static assert(messageTypeFullName_.length != 0); 12 13 private struct _Message 14 { 15 @Proto(1) T value = protoDefaultValue!T; 16 } 17 18 Nullable!T value; 19 20 alias value this; 21 22 inout this(inout T value) 23 { 24 this.value = value; 25 } 26 27 auto toProtobuf() 28 { 29 return _Message(value).toProtobuf; 30 } 31 32 auto fromProtobuf(R)(ref R inputRange) 33 { 34 value = inputRange.fromProtobuf!_Message.value; 35 return this; 36 } 37 38 JSONValue toJSONValue()() 39 { 40 import google.protobuf.json_encoding; 41 42 return value.isNull ? JSONValue(null) : value.get.toJSONValue; 43 } 44 45 auto fromJSONValue()(JSONValue jsonValue) 46 { 47 import google.protobuf.json_encoding; 48 49 if (jsonValue.isNull) 50 value.nullify; 51 else 52 value = jsonValue.fromJSONValue!T; 53 return this; 54 } 55 } 56 57 alias DoubleValue = WrappedValue!(double, "google.protobuf.DoubleValue"); 58 alias FloatValue = WrappedValue!(float, "google.protobuf.FloatValue"); 59 alias Int64Value = WrappedValue!(long, "google.protobuf.Int64Value"); 60 alias UInt64Value = WrappedValue!(ulong, "google.protobuf.UInt64Value"); 61 alias Int32Value = WrappedValue!(int, "google.protobuf.Int32Value"); 62 alias UInt32Value = WrappedValue!(uint, "google.protobuf.UInt32Value"); 63 alias BoolValue = WrappedValue!(bool, "google.protobuf.BoolValue"); 64 alias StringValue = WrappedValue!(string, "google.protobuf.StringValue"); 65 alias BytesValue = WrappedValue!(bytes, "google.protobuf.BytesValue"); 66 67 unittest 68 { 69 import std.algorithm.comparison : equal; 70 import std.array : array, empty; 71 import std.meta : AliasSeq; 72 73 auto buffer = Int64Value(10).toProtobuf.array; 74 assert(equal(buffer, [0x08, 0x0a])); 75 assert(buffer.fromProtobuf!UInt32Value == 10); 76 77 assert(buffer.empty); 78 foreach (WrappedValue; AliasSeq!(DoubleValue, FloatValue, Int64Value, UInt64Value, Int32Value, UInt32Value, 79 BoolValue, StringValue, BytesValue)) 80 { 81 static assert(protoDefaultValue!WrappedValue.isNull); 82 assert(buffer.fromProtobuf!WrappedValue == protoDefaultValue!(typeof(WrappedValue.value.get))); 83 } 84 }