From 8e0a5f1e73313a667550ab578023cba40664c953 Mon Sep 17 00:00:00 2001 From: dushibaiyu Date: Tue, 13 Dec 2016 19:33:55 +0800 Subject: [PATCH 1/4] Beautify the generated code and add type --- dprotoc/src/app.d | 16 ++++- examples/proto/person.d | 70 +++++++++++++++++++ examples/proto/person.proto | 16 ++++- import/dproto/intermediate.d | 131 +++++++++++++++++++---------------- 4 files changed, 170 insertions(+), 63 deletions(-) create mode 100644 examples/proto/person.d diff --git a/dprotoc/src/app.d b/dprotoc/src/app.d index 2975fdf..eb73017 100644 --- a/dprotoc/src/app.d +++ b/dprotoc/src/app.d @@ -5,6 +5,7 @@ import std.stdio; import std.string; import dproto.parse; import dproto.intermediate; +import std.format; auto openFileComplex(string fn, string mode) { @@ -22,11 +23,15 @@ void main(string[] args) { string infile = "-"; string outfile = "-"; - string fmt = "%d"; + string fmt = "%s"; + char syntx = 'd'; + int servicetype = 1; auto helpInformation = getopt( args, "out|o", "Output filename (default stdout)", &outfile, "format|f", "Code generation format", &fmt, + "syntx|s", "code generation syntx. it should be : \n\t\t\td : dlang file; \n\t\t\ts : dlang code string;\n\t\t\tp : protobuf file.",&syntx, + "type|t", "what dlang file or code string will create service to. it should be :\n\t\t\t1 : interface N { R metond(P);}\n\t\t\t2 : interface N { void metond(const P, ref R);}\n\t\t\t3 : class N { R metond(P){R res;return res;}}",&servicetype ); if (helpInformation.helpWanted) { @@ -45,5 +50,12 @@ void main(string[] args) } pack = ParseProtoSchema(infile, inf.byLine.join("\n").idup); } - openFileComplex(outfile, "w").write(fmt.format(pack)); + auto file = openFileComplex(outfile, "w"); + + FormatSpec!char thefmt = FormatSpec!char(fmt); + thefmt.spec = syntx; + thefmt.precision = servicetype; + Appender!string buffer; + pack.toString((const(char)[] data){buffer.put(data);},thefmt); + file.write(fmt.format(buffer.data)); } diff --git a/examples/proto/person.d b/examples/proto/person.d new file mode 100644 index 0000000..3537168 --- /dev/null +++ b/examples/proto/person.d @@ -0,0 +1,70 @@ +package persion; + +import std.range; +import dproto.serialize; + +static struct Person { + static import dproto.attributes; + mixin dproto.attributes.ProtoAccessors; + +enum PhoneType { + WORK = 2, + HOME = 0, + MOBILE = 0, +} + +static struct PhoneNumber { + static import dproto.attributes; + mixin dproto.attributes.ProtoAccessors; + + @(dproto.attributes.Required()) + @(dproto.attributes.ProtoField("string", 1)) + BuffType!"string" number= UnspecifiedDefaultValue!(BuffType!"string"); + + + @(dproto.attributes.ProtoField("PhoneType", 2)) + dproto.serialize.PossiblyNullable!(PhoneType) type= SpecifiedDefaultValue!(PhoneType, "MOBILE"); + +} + + @(dproto.attributes.Required()) + @(dproto.attributes.ProtoField("string", 1)) + BuffType!"string" name= UnspecifiedDefaultValue!(BuffType!"string"); + + + @(dproto.attributes.Required()) + @(dproto.attributes.ProtoField("int32", 2)) + BuffType!"int32" id= UnspecifiedDefaultValue!(BuffType!"int32"); + + + @(dproto.attributes.ProtoField("string", 3)) + BuffType!"string" email= UnspecifiedDefaultValue!(BuffType!"string"); + + + @(dproto.attributes.ProtoField("PhoneNumber", 4)) + PhoneNumber[] phone; + +} + +static struct ServiceRequest { + static import dproto.attributes; + mixin dproto.attributes.ProtoAccessors; + + @(dproto.attributes.ProtoField("string", 1)) + BuffType!"string" request= UnspecifiedDefaultValue!(BuffType!"string"); + +} + +static struct ServiceResponse { + static import dproto.attributes; + mixin dproto.attributes.ProtoAccessors; + + @(dproto.attributes.ProtoField("string", 1)) + BuffType!"string" response= UnspecifiedDefaultValue!(BuffType!"string"); + +} + +interface TestService { + ServiceResponse TestMethod (ServiceRequest); +} + diff --git a/examples/proto/person.proto b/examples/proto/person.proto index 0145f0a..132375c 100644 --- a/examples/proto/person.proto +++ b/examples/proto/person.proto @@ -1,5 +1,7 @@ +package persion; + message Person { - required string name = 1; + required string name = 1; // namnmknhi required int32 id = 2; optional string email = 3; @@ -16,3 +18,15 @@ message Person { repeated PhoneNumber phone = 4; } + + +message ServiceRequest { + string request = 1; +} +message ServiceResponse { + string response = 1; +} + +service TestService { + rpc TestMethod (ServiceRequest) returns (ServiceResponse); +} diff --git a/import/dproto/intermediate.d b/import/dproto/intermediate.d index 0445826..43fb65e 100644 --- a/import/dproto/intermediate.d +++ b/import/dproto/intermediate.d @@ -17,6 +17,52 @@ import std.conv; import std.string; import std.format; +struct ProtoPackage { + this(string fileName) { + this.fileName = fileName.idup; + } + string fileName; + string packageName; + Dependency[] dependencies; + EnumType[] enumTypes; + MessageType[] messageTypes; + Options options; + Service[] rpcServices; + string syntax = "proto2"; + + const void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) + { + if(fmt.spec == 'p' || fmt.spec == 'd') { + if(packageName) { + sink.formattedWrite("package %s; \n\n", packageName); + } + if(syntax != "proto2") { + sink.formattedWrite(`syntax = %s; \n`, syntax); + } + } + if(fmt.spec == 'd'){ + sink("import std.range;\nimport dproto.serialize;\n"); + } + foreach(dep; dependencies) { + dep.toString(sink, fmt); + sink("\n"); + } + sink("\n"); + foreach(e; enumTypes){ e.toString(sink, fmt);sink("\n");} + foreach(m; messageTypes){ m.toString(sink, fmt); sink("\n");} + foreach(r; rpcServices){r.toString(sink, fmt);sink("\n");} + if(fmt.spec == 'p') { + foreach(opt, val; options) { + sink.formattedWrite("option %s = %s; \n", opt, val); + } + } + } + + string toProto() @property const { return "%p".format(this); } + string toD() @property const { return "%s".format(this); } +} + + package: struct Options { @@ -48,18 +94,19 @@ struct MessageType { if(fmt.spec == 'p') { sink.formattedWrite("message %s { ", name); foreach(opt, val; options) { - sink.formattedWrite("option %s = %s; ", opt, val); + sink.formattedWrite("\toption %s = %s; ", opt, val); } } else { sink.formattedWrite("static struct %s {\n", name); // Methods for serialization and deserialization. - sink("static import dproto.attributes;\n"); + sink("\tstatic import dproto.attributes;\n\t"); sink(`mixin dproto.attributes.ProtoAccessors;`); + sink("\n"); } - foreach(et; enumTypes) et.toString(sink, fmt); - foreach(mt; messageTypes) mt.toString(sink, fmt); - foreach(field; fields) field.toString(sink, fmt); + foreach(et; enumTypes){sink("\n");et.toString(sink, fmt);} + foreach(mt; messageTypes){sink("\n"); mt.toString(sink, fmt);} + foreach(field; fields){sink("\n"); field.toString(sink, fmt);} sink("}\n"); } @@ -80,12 +127,12 @@ struct EnumType { string suffix = ", "; if(fmt.spec == 'p') { foreach(opt, val; options) { - sink.formattedWrite("option %s = %s; ", opt, val); + sink.formattedWrite("\toption %s = %s; \n", opt, val); } suffix = "; "; } foreach(key, val; values) { - sink.formattedWrite("%s = %s%s", key, val, suffix); + sink.formattedWrite("\t%s = %s%s \n", key, val, suffix); } sink("}\n"); } @@ -117,7 +164,9 @@ struct Dependency { const void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) { - if(fmt.spec == 'p') { + if(fmt.spec == 'p' || fmt.spec == 'd') { + if(fmt.spec == 'd') + sink("\n//NOTE: please change your import module.\n"); sink("import "); if(isPublic) { sink("public "); @@ -131,46 +180,6 @@ struct Dependency { string toD() @property const { return "%s".format(this); } } -struct ProtoPackage { - this(string fileName) { - this.fileName = fileName.idup; - } - string fileName; - string packageName; - Dependency[] dependencies; - EnumType[] enumTypes; - MessageType[] messageTypes; - Options options; - Service[] rpcServices; - string syntax = "proto2"; - - const void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) - { - if(fmt.spec == 'p') { - if(packageName) { - sink.formattedWrite("package %s; ", packageName); - } - if(syntax != "proto2") { - sink.formattedWrite(`syntax = %s; `, syntax); - } - } - foreach(dep; dependencies) { - dep.toString(sink, fmt); - } - foreach(e; enumTypes) e.toString(sink, fmt); - foreach(m; messageTypes) m.toString(sink, fmt); - foreach(r; rpcServices) r.toString(sink, fmt); - if(fmt.spec == 'p') { - foreach(opt, val; options) { - sink.formattedWrite("option %s = %s; ", opt, val); - } - } - } - - string toProto() @property const { return "%p".format(this); } - string toD() @property const { return "%s".format(this); } -} - struct Field { enum Requirement { OPTIONAL, @@ -202,11 +211,11 @@ struct Field { switch(fmt.spec) { case 'p': if(fmt.width == 3 && requirement != Requirement.REPEATED) { - sink.formattedWrite("%s %s = %s%p; ", + sink.formattedWrite("\t%s %s = %s%p; \n", type, name, id, options); } else { - sink.formattedWrite("%s %s %s = %s%p; ", + sink.formattedWrite("\t%s %s %s = %s%p; \n", requirement.to!string.toLower(), type, name, id, options); } @@ -215,7 +224,7 @@ struct Field { if(!fmt.flDash) { getDeclaration(sink); } else { - sink.formattedWrite("%s %s;\n", + sink.formattedWrite("\t%s %s;\n", type, name); } break; @@ -224,13 +233,13 @@ struct Field { void getDeclaration(scope void delegate(const(char)[]) sink) const { if(requirement == Requirement.REQUIRED) { - sink("@(dproto.attributes.Required())\n"); + sink("\t@(dproto.attributes.Required())\n"); } else if(requirement == Requirement.REPEATED) { if(options.get("packed", "false") != "false") { - sink("@(dproto.attributes.Packed())\n"); + sink("\t@(dproto.attributes.Packed())\n"); } } - sink("@(dproto.attributes.ProtoField"); + sink("\t@(dproto.attributes.ProtoField"); sink.formattedWrite(`("%s", %s)`, type, id); sink(")\n"); @@ -239,13 +248,15 @@ struct Field { ! type.isBuiltinType(); if(wrap_with_nullable) { + sink("\t"); sink(`dproto.serialize.PossiblyNullable!(`); } string typestr = type; if(type.isBuiltinType) { typestr = format(`BuffType!"%s"`, type); } - + if(!wrap_with_nullable) + sink("\t"); sink(typestr); if(wrap_with_nullable) { @@ -300,11 +311,11 @@ struct Service { { switch(fmt.spec) { case 'p': - sink.formattedWrite("rpc %s (%s) returns (%s)", name, requestType, responseType); + sink.formattedWrite("\trpc %s (%s) returns (%s)", name, requestType, responseType); if(options.length > 0) { sink(" {\n"); foreach(opt, val; options) { - sink.formattedWrite("option %s = %s;\n", opt, val); + sink.formattedWrite("\toption %s = %s;\n", opt, val); } sink("}\n"); } else { @@ -313,11 +324,11 @@ struct Service { break; default: if(fmt.precision == 3) { - sink.formattedWrite("%s %s (%s) { %s res; return res; }\n", responseType, name, requestType, responseType); + sink.formattedWrite("\t%s %s (%s) { %s res; return res; }\n", responseType, name, requestType, responseType); } else if(fmt.precision == 2) { - sink.formattedWrite("void %s (const %s, ref %s);\n", name, requestType, responseType); + sink.formattedWrite("\tvoid %s (const %s, ref %s);\n", name, requestType, responseType); } else if(fmt.precision == 1) { - sink.formattedWrite("%s %s (%s);\n", responseType, name, requestType); + sink.formattedWrite("\t%s %s (%s);\n", responseType, name, requestType); } break; } From ef4f1a8f9f206255067065b63f28ce61510f0a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A1=E4=B8=96=E7=99=BD=E7=8E=89?= Date: Tue, 13 Dec 2016 22:20:06 +0800 Subject: [PATCH 2/4] fix module --- import/dproto/intermediate.d | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/import/dproto/intermediate.d b/import/dproto/intermediate.d index 43fb65e..2dfac66 100644 --- a/import/dproto/intermediate.d +++ b/import/dproto/intermediate.d @@ -32,15 +32,17 @@ struct ProtoPackage { const void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) { - if(fmt.spec == 'p' || fmt.spec == 'd') { + if(fmt.spec == 'p') { if(packageName) { sink.formattedWrite("package %s; \n\n", packageName); } if(syntax != "proto2") { sink.formattedWrite(`syntax = %s; \n`, syntax); } - } - if(fmt.spec == 'd'){ + }else if(fmt.spec == 'd'){ + if(packageName) { + sink.formattedWrite("module %s; \n\n", packageName); + } sink("import std.range;\nimport dproto.serialize;\n"); } foreach(dep; dependencies) { From d92f78f308e8b9316e7aee432f47638415fbcb2d Mon Sep 17 00:00:00 2001 From: dushibaiyu Date: Thu, 15 Dec 2016 16:40:30 +0800 Subject: [PATCH 3/4] use config --- dprotoc/src/app.d | 23 ++++-- import/dproto/intermediate.d | 146 ++++++++++++++++++----------------- import/dproto/unittests.d | 7 +- 3 files changed, 98 insertions(+), 78 deletions(-) diff --git a/dprotoc/src/app.d b/dprotoc/src/app.d index eb73017..5dc4a08 100644 --- a/dprotoc/src/app.d +++ b/dprotoc/src/app.d @@ -23,13 +23,11 @@ void main(string[] args) { string infile = "-"; string outfile = "-"; - string fmt = "%s"; char syntx = 'd'; int servicetype = 1; auto helpInformation = getopt( args, "out|o", "Output filename (default stdout)", &outfile, - "format|f", "Code generation format", &fmt, "syntx|s", "code generation syntx. it should be : \n\t\t\td : dlang file; \n\t\t\ts : dlang code string;\n\t\t\tp : protobuf file.",&syntx, "type|t", "what dlang file or code string will create service to. it should be :\n\t\t\t1 : interface N { R metond(P);}\n\t\t\t2 : interface N { void metond(const P, ref R);}\n\t\t\t3 : class N { R metond(P){R res;return res;}}",&servicetype ); @@ -52,10 +50,21 @@ void main(string[] args) } auto file = openFileComplex(outfile, "w"); - FormatSpec!char thefmt = FormatSpec!char(fmt); - thefmt.spec = syntx; - thefmt.precision = servicetype; + ProtoConfig fmt; + fmt.rpc = servicetype; + final switch(syntx){ + case 'p': + fmt.type = ProtoConfig.Type.Proto; + break; + case 's' : + fmt.type = ProtoConfig.Type.Dcode; + break; + case 'd' : + fmt.type = ProtoConfig.Type.Dfile; + break; + } + Appender!string buffer; - pack.toString((const(char)[] data){buffer.put(data);},thefmt); - file.write(fmt.format(buffer.data)); + pack.toString((const(char)[] data){buffer.put(data);},fmt); + file.write(buffer.data); } diff --git a/import/dproto/intermediate.d b/import/dproto/intermediate.d index 2dfac66..3255dc5 100644 --- a/import/dproto/intermediate.d +++ b/import/dproto/intermediate.d @@ -17,6 +17,16 @@ import std.conv; import std.string; import std.format; +struct ProtoConfig{ + enum Type{ + Proto, + Dcode, + Dfile + } + Type type = Type.Dcode; + int rpc = 1; +} + struct ProtoPackage { this(string fileName) { this.fileName = fileName.idup; @@ -30,16 +40,16 @@ struct ProtoPackage { Service[] rpcServices; string syntax = "proto2"; - const void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) + const void toString(scope void delegate(const(char)[]) sink,ProtoConfig fmt = ProtoConfig()) { - if(fmt.spec == 'p') { + if(fmt.type == ProtoConfig.Type.Proto) { if(packageName) { sink.formattedWrite("package %s; \n\n", packageName); } if(syntax != "proto2") { sink.formattedWrite(`syntax = %s; \n`, syntax); } - }else if(fmt.spec == 'd'){ + }else if(fmt.type == ProtoConfig.Type.Dfile){ if(packageName) { sink.formattedWrite("module %s; \n\n", packageName); } @@ -53,15 +63,27 @@ struct ProtoPackage { foreach(e; enumTypes){ e.toString(sink, fmt);sink("\n");} foreach(m; messageTypes){ m.toString(sink, fmt); sink("\n");} foreach(r; rpcServices){r.toString(sink, fmt);sink("\n");} - if(fmt.spec == 'p') { + if(fmt.type == ProtoConfig.Type.Proto) { foreach(opt, val; options) { sink.formattedWrite("option %s = %s; \n", opt, val); } } } - string toProto() @property const { return "%p".format(this); } - string toD() @property const { return "%s".format(this); } + string toProto() @property const { + import std.array; + Appender!string data = appender!string(); + ProtoConfig fmt; + fmt.type = ProtoConfig.Type.Proto; + toString((const(char)[] str){data.put(str);},fmt); + return data.data; + } + string toD() @property const { + import std.array; + Appender!string data = appender!string(); + toString((const(char)[] str){data.put(str);}); + return data.data; + } } @@ -91,9 +113,9 @@ struct MessageType { EnumType[] enumTypes; MessageType[] messageTypes; - const void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) + const void toString(scope void delegate(const(char)[]) sink, ref ProtoConfig fmt) { - if(fmt.spec == 'p') { + if(fmt.type == ProtoConfig.Type.Proto) { sink.formattedWrite("message %s { ", name); foreach(opt, val; options) { sink.formattedWrite("\toption %s = %s; ", opt, val); @@ -112,7 +134,7 @@ struct MessageType { sink("}\n"); } - string toD() @property const { return "%s".format(this); } + string toD() @property const {return "%s".format(this); } } struct EnumType { @@ -123,11 +145,11 @@ struct EnumType { Options options; int[string] values; - const void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) + const void toString(scope void delegate(const(char)[]) sink, ref ProtoConfig fmt) { sink.formattedWrite("enum %s {\n", name); string suffix = ", "; - if(fmt.spec == 'p') { + if(fmt.type == ProtoConfig.Type.Proto) { foreach(opt, val; options) { sink.formattedWrite("\toption %s = %s; \n", opt, val); } @@ -164,16 +186,20 @@ struct Dependency { string name; bool isPublic; - const void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) + const void toString(scope void delegate(const(char)[]) sink,ref ProtoConfig fmt) { - if(fmt.spec == 'p' || fmt.spec == 'd') { - if(fmt.spec == 'd') - sink("\n//NOTE: please change your import module.\n"); + if(fmt.type == ProtoConfig.Type.Proto) { sink("import "); if(isPublic) { sink("public "); } sink.formattedWrite(`"%s"; `, name); + } else if(fmt.type == ProtoConfig.Type.Dfile){ + sink("\n//NOTE: please change your import module.\n"); + if(isPublic) { + sink("public "); + } + sink.formattedWrite(`import "%s"; `, name); } else { sink.formattedWrite(`mixin ProtocolBuffer!"%s";`, name); } @@ -208,28 +234,14 @@ struct Field { return options["default"]; } - const void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) + const void toString(scope void delegate(const(char)[]) sink, ref ProtoConfig fmt) { - switch(fmt.spec) { - case 'p': - if(fmt.width == 3 && requirement != Requirement.REPEATED) { - sink.formattedWrite("\t%s %s = %s%p; \n", - type, name, id, options); - } - else { - sink.formattedWrite("\t%s %s %s = %s%p; \n", - requirement.to!string.toLower(), - type, name, id, options); - } - break; - default: - if(!fmt.flDash) { - getDeclaration(sink); - } else { - sink.formattedWrite("\t%s %s;\n", - type, name); - } - break; + if(fmt.type == ProtoConfig.Type.Proto){ + sink.formattedWrite("\t%s %s %s = %s%p; \n", + requirement.to!string.toLower(), + type, name, id, options); + } else { + getDeclaration(sink); } } @@ -309,49 +321,43 @@ struct Service { string responseType; Options options; - const void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) + const void toString(scope void delegate(const(char)[]) sink, ref ProtoConfig fmt) { - switch(fmt.spec) { - case 'p': - sink.formattedWrite("\trpc %s (%s) returns (%s)", name, requestType, responseType); - if(options.length > 0) { - sink(" {\n"); - foreach(opt, val; options) { - sink.formattedWrite("\toption %s = %s;\n", opt, val); - } - sink("}\n"); - } else { - sink(";\n"); - } - break; - default: - if(fmt.precision == 3) { - sink.formattedWrite("\t%s %s (%s) { %s res; return res; }\n", responseType, name, requestType, responseType); - } else if(fmt.precision == 2) { - sink.formattedWrite("\tvoid %s (const %s, ref %s);\n", name, requestType, responseType); - } else if(fmt.precision == 1) { - sink.formattedWrite("\t%s %s (%s);\n", responseType, name, requestType); + if(fmt.type == ProtoConfig.Type.Proto){ + sink.formattedWrite("\trpc %s (%s) returns (%s)", name, requestType, responseType); + if(options.length > 0) { + sink(" {\n"); + foreach(opt, val; options) { + sink.formattedWrite("\toption %s = %s;\n", opt, val); } - break; + sink("}\n"); + } else { + sink(";\n"); + } + } else { + if(fmt.rpc == 3) { + sink.formattedWrite("\t%s %s (%s) { %s res; return res; }\n", responseType, name, requestType, responseType); + } else if(fmt.rpc == 2) { + sink.formattedWrite("\tvoid %s (const %s, ref %s);\n", name, requestType, responseType); + } else if(fmt.rpc == 1) { + sink.formattedWrite("\t%s %s (%s);\n", responseType, name, requestType); + } } } } - const void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) + const void toString(scope void delegate(const(char)[]) sink, ref ProtoConfig fmt) { - switch(fmt.spec) { - case 'p': + if(fmt.type == ProtoConfig.Type.Proto){ sink.formattedWrite("service %s {\n", name); - break; - default: - if(fmt.precision == 3) { + } else { + if(fmt.rpc == 3) { sink.formattedWrite("class %s {\n", name); - } else if(fmt.precision == 2 || fmt.precision == 1) { - sink.formattedWrite("interface %s {\n", name); - } else { - return; - } - break; + } else if(fmt.rpc == 2 || fmt.rpc == 1) { + sink.formattedWrite("interface %s {\n", name); + } else { + return; + } } foreach(m; rpc) m.toString(sink, fmt); sink("}\n"); diff --git a/import/dproto/unittests.d b/import/dproto/unittests.d index dc4902c..7fe1fb6 100644 --- a/import/dproto/unittests.d +++ b/import/dproto/unittests.d @@ -11,6 +11,8 @@ module dproto.unittests; import dproto.dproto; +import std.stdio; + unittest { assert(__traits(compiles, ProtocolBufferFromString!"message Test @@ -575,9 +577,12 @@ unittest import dproto.parse; import std.string : strip; - auto proto_src = `import "foo/baz.proto";`; + auto proto_src = `import "foo/baz.proto";` ~ "\n\n"; auto proto_struct = ParseProtoSchema("", proto_src); auto d_src = proto_struct.toD; + writeln(d_src); + writeln(cast(ubyte[])proto_src); + writeln(cast(ubyte[])d_src); assert(`mixin ProtocolBuffer!"foo/baz.proto";` == d_src, "Mixin string should not have two double quotes " ~ d_src); assert(proto_src == proto_struct.toProto.strip, From d9f3d91da7f723a5c6519b0fb3a6988547ac2178 Mon Sep 17 00:00:00 2001 From: dushibaiyu Date: Thu, 15 Dec 2016 16:54:49 +0800 Subject: [PATCH 4/4] unittest --- import/dproto/unittests.d | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/import/dproto/unittests.d b/import/dproto/unittests.d index 7fe1fb6..3a94bc7 100644 --- a/import/dproto/unittests.d +++ b/import/dproto/unittests.d @@ -194,11 +194,7 @@ unittest // Force code coverage in doveralls import std.string; - import std.format; import dproto.parse; - - auto normalizedServiceDefinition = "%3.3p".format(ParseProtoSchema("", serviceDefinition)); - assert(__traits(compiles, ProtocolBufferFromString!serviceDefinition)); assert(__traits(compiles, ProtocolBufferInterface!serviceDefinition)); assert(__traits(compiles, ProtocolBufferRpc!serviceDefinition)); @@ -577,13 +573,10 @@ unittest import dproto.parse; import std.string : strip; - auto proto_src = `import "foo/baz.proto";` ~ "\n\n"; + auto proto_src = `import "foo/baz.proto";`; auto proto_struct = ParseProtoSchema("", proto_src); auto d_src = proto_struct.toD; - writeln(d_src); - writeln(cast(ubyte[])proto_src); - writeln(cast(ubyte[])d_src); - assert(`mixin ProtocolBuffer!"foo/baz.proto";` == d_src, + assert(`mixin ProtocolBuffer!"foo/baz.proto";` == d_src.strip, "Mixin string should not have two double quotes " ~ d_src); assert(proto_src == proto_struct.toProto.strip, "Round tripping to protobuf source should yield starting text " ~ proto_struct.toProto); @@ -728,11 +721,8 @@ unittest // Force code coverage in doveralls import std.string; - import std.format; import dproto.parse; - auto normalizedServiceDefinition = "%3.3p".format(ParseProtoSchema("", pbstring)); - mixin ProtocolBufferFromString!pbstring; Msg msg;