Skip to content

Commit

Permalink
Allow empty messages
Browse files Browse the repository at this point in the history
  • Loading branch information
dcarp committed Dec 20, 2018
1 parent 35a9281 commit 7b9a4bc
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/google/protobuf/common.d
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ template Message(T)

alias fieldNames = staticMap!(fieldName, fields);

static assert(fields.length > 0, "Definition of '" ~ T.stringof ~ "' has no Proto field");
static assert(allSatisfy!(validateField, fields), "'" ~ T.stringof ~ "' has invalid fields");

private alias unsortedFields = getSymbolsByUDA!(T, Proto);
Expand All @@ -165,6 +164,13 @@ unittest

static assert(Message!Test.fieldNames == AliasSeq!("bar", "foo"));
static assert(Message!Test.protos == AliasSeq!(Proto(2, Wire.fixed, No.packed), Proto(3, Wire.none, No.packed)));

static class EmptyMessage
{
}

static assert(is(Message!EmptyMessage.fieldNames == AliasSeq!()));
static assert(is(Message!EmptyMessage.protos == AliasSeq!()));
}

template validateField(alias field)
Expand Down
11 changes: 11 additions & 0 deletions src/google/protobuf/decoding.d
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,17 @@ unittest
assert(foo.qux);
}

unittest
{
static class EmptyMessage
{
}

ubyte[] buff = [];
auto emptyMessage = buff.fromProtobuf!EmptyMessage;
assert(buff.empty);
}

private static void fromProtobufByField(alias field, T, R)(ref R inputRange, ref T message)
if (isInputRange!R)
{
Expand Down
17 changes: 17 additions & 0 deletions src/google/protobuf/encoding.d
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,17 @@ unittest
auto toProtobuf(T)(T value)
if (is(T == class) || is(T == struct))
{
import std.meta : AliasSeq;
import std.traits : hasMember;

static if (hasMember!(T, "toProtobuf"))
{
return value.toProtobuf;
}
else static if (is(Message!T.fields == AliasSeq!()))
{
return cast(ubyte[]) null;
}
else
{
import std.algorithm : joiner;
Expand Down Expand Up @@ -188,6 +193,18 @@ unittest
assert(foo.toProtobuf.array == [0x08, 0x05, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01]);
}

unittest
{
import std.array : array;

struct EmptyMessage
{
}

EmptyMessage emptyMessage;
assert(emptyMessage.toProtobuf.empty);
}

unittest
{
struct Foo
Expand Down
12 changes: 12 additions & 0 deletions src/google/protobuf/json_decoding.d
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,18 @@ unittest
assertThrown!ProtobufException(fromJSONValue!Foo(parseJSON(`{"d":10, "e":"abc"}`)));
}

unittest
{
import std.json : parseJSON;

struct EmptyMessage
{
}

assert(fromJSONValue!EmptyMessage(parseJSON(`{}`)) == EmptyMessage());
assert(fromJSONValue!EmptyMessage(parseJSON(`{"a":10, "b":"abc"}`)) == EmptyMessage());
}

private template oneofs(T)
{
import std.meta : NoDuplicates, staticMap;
Expand Down
13 changes: 13 additions & 0 deletions src/google/protobuf/json_encoding.d
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,19 @@ unittest
assert(foo.toJSONValue == parseJSON(`{"a":10, "b":"abc"}`));
}

unittest
{
import std.json : parseJSON;

struct EmptyMessage
{
}

EmptyMessage emptyMessage;

assert(emptyMessage.toJSONValue == parseJSON(`{}`));
}

unittest
{
import std.json : parseJSON;
Expand Down

0 comments on commit 7b9a4bc

Please sign in to comment.