diff options
| author | Oskari Timperi <oskari.timperi@iki.fi> | 2018-04-08 16:13:00 +0300 |
|---|---|---|
| committer | Oskari Timperi <oskari.timperi@iki.fi> | 2018-04-08 16:13:00 +0300 |
| commit | d94b73731fb7da1f42f2bf0a6293070690bb9a5c (patch) | |
| tree | 492c6d0f0a7ae5d77e2c3001296ccb695549c99d | |
| parent | c065aed3140018bd2717566b21ec462c45ffe2a1 (diff) | |
| download | nimpb-d94b73731fb7da1f42f2bf0a6293070690bb9a5c.tar.gz nimpb-d94b73731fb7da1f42f2bf0a6293070690bb9a5c.zip | |
Add initial message to JSON serialization support
| -rw-r--r-- | src/nimpb/json.nim | 209 | ||||
| -rw-r--r-- | src/nimpb/wkt/any_pb.nim | 3 | ||||
| -rw-r--r-- | src/nimpb/wkt/api_pb.nim | 59 | ||||
| -rw-r--r-- | src/nimpb/wkt/duration_pb.nim | 3 | ||||
| -rw-r--r-- | src/nimpb/wkt/empty_pb.nim | 7 | ||||
| -rw-r--r-- | src/nimpb/wkt/field_mask_pb.nim | 3 | ||||
| -rw-r--r-- | src/nimpb/wkt/source_context_pb.nim | 9 | ||||
| -rw-r--r-- | src/nimpb/wkt/struct_pb.nim | 3 | ||||
| -rw-r--r-- | src/nimpb/wkt/timestamp_pb.nim | 3 | ||||
| -rw-r--r-- | src/nimpb/wkt/type_pb.nim | 96 | ||||
| -rw-r--r-- | src/nimpb/wkt/wrappers_pb.nim | 3 | ||||
| -rw-r--r-- | tests/conformance/conformance_nim.nim | 20 | ||||
| -rw-r--r-- | tests/conformance/failures.txt | 18 |
13 files changed, 431 insertions, 5 deletions
diff --git a/src/nimpb/json.nim b/src/nimpb/json.nim new file mode 100644 index 0000000..28cd0f5 --- /dev/null +++ b/src/nimpb/json.nim @@ -0,0 +1,209 @@ +import base64 +import math +import std/json +import strutils +import times + +import nimpb + +import wkt/duration_pb +import wkt/timestamp_pb +import wkt/wrappers_pb +import wkt/field_mask_pb +import wkt/struct_pb +import wkt/any_pb + +proc `%`*(u: uint32): JsonNode = + newJFloat(float(u)) + +proc `%`*(b: bytes): JsonNode = + result = newJString(base64.encode(string(b), newLine="")) + +proc toJson*(value: float): JsonNode = + case classify(value) + of fcNan: result = %"NaN" + of fcInf: result = %"Infinity" + of fcNegInf: result = %"-Infinity" + else: result = %value + +proc toJson*(value: float32): JsonNode = + case classify(value) + of fcNan: result = %"NaN" + of fcInf: result = %"Infinity" + of fcNegInf: result = %"-Infinity" + else: result = %value + +proc toJson*(value: int64): JsonNode = + newJString($value) + +proc toJson*(value: uint64): JsonNode = + newJString($value) + +proc toJson*(message: google_protobuf_DoubleValue): JsonNode = + if hasValue(message): + result = toJson(message.value) + else: + result = newJNull() + +proc toJson*(message: google_protobuf_FloatValue): JsonNode = + if hasValue(message): + result = toJson(message.value) + else: + result = newJNull() + +proc toJson*(message: google_protobuf_Int64Value): JsonNode = + if hasValue(message): + result = toJson(message.value) + else: + result = newJNull() + +proc toJson*(message: google_protobuf_UInt64Value): JsonNode = + if hasValue(message): + result = toJson(message.value) + else: + result = newJNull() + +proc toJson*(message: google_protobuf_Int32Value): JsonNode = + if hasValue(message): + result = %message.value + else: + result = newJNull() + +proc toJson*(message: google_protobuf_UInt32Value): JsonNode = + if hasValue(message): + result = %message.value + else: + result = newJNull() + +proc toJson*(message: google_protobuf_BoolValue): JsonNode = + if hasValue(message): + result = %message.value + else: + result = newJNull() + +proc toJson*(message: google_protobuf_StringValue): JsonNode = + if hasValue(message): + result = %message.value + else: + result = newJNull() + +proc toJson*(message: google_protobuf_BytesValue): JsonNode = + if hasValue(message): + result = %message.value + else: + result = newJNull() + +proc toJson*(message: google_protobuf_Duration): JsonNode = + if (message.seconds < -315_576_000_000'i64) or + (message.seconds > 315_576_000_000'i64): + raise newException(ValueError, "seconds out of bounds") + + if (message.nanos < -999_999_999'i32) or + (message.nanos > 999_999_999'i32): + raise newException(ValueError, "nanos out of bounds") + + if message.seconds != 0: + if sgn(message.seconds) != sgn(message.nanos): + raise newException(ValueError, "different sign for seconds and nanos") + + var s = $message.seconds + + if message.nanos != 0: + add(s, ".") + add(s, intToStr(message.nanos, 9)) + removeSuffix(s, '0') + + add(s, "s") + + result = %s + +proc toJson*(message: google_protobuf_Timestamp): JsonNode = + let t = utc(fromUnix(message.seconds)) + + if t.year < 1 or t.year > 9999: + raise newException(ValueError, "invalid timestamp") + + var s = format(t, "yyyy-MM-dd'T'HH:mm:ss") + if message.nanos != 0: + add(s, ".") + add(s, intToStr(message.nanos, 9)) + removeSuffix(s, '0') + add(s, "Z") + result = %s + +proc toJson*(message: google_protobuf_FieldMask): JsonNode = + %join(message.paths, ",") + +proc toJson*(message: google_protobuf_Value): JsonNode + +proc toJson*(message: google_protobuf_Struct): JsonNode = + result = newJObject() + for key, value in message.fields: + result[key] = toJson(value) + +proc toJson*(message: google_protobuf_ListValue): JsonNode + +proc toJson*(message: google_protobuf_Value): JsonNode = + if hasNullValue(message): + result = newJNull() + elif hasNumberValue(message): + result = toJson(message.numberValue) + elif hasStringValue(message): + result = %message.stringValue + elif hasBoolValue(message): + result = %message.boolValue + elif hasStructValue(message): + result = toJson(message.structValue) + elif hasListValue(message): + result = toJson(message.listValue) + else: + raise newException(ValueError, "no field set") + +proc toJson*(message: google_protobuf_NullValue): JsonNode = + newJNull() + +proc toJson*(message: google_protobuf_ListValue): JsonNode = + result = newJArray() + for value in message.values: + add(result, toJson(value)) + +proc toJson*(message: google_protobuf_Any): JsonNode = + case message.typeUrl + of "type.googleapis.com/google.protobuf.Duration": + let duration = newGoogleProtobufDuration(string(message.value)) + result = newJObject() + result["@type"] = %message.typeUrl + result["value"] = toJson(duration) + of "type.googleapis.com/google.protobuf.Empty": + result = newJObject() + result["@type"] = %message.typeUrl + result["value"] = newJObject() + of "type.googleapis.com/google.protobuf.FieldMask": + let mask = newGoogleProtobufFieldMask(string(message.value)) + result = newJObject() + result["@type"] = %message.typeUrl + result["value"] = toJson(mask) + of "type.googleapis.com/google.protobuf.Struct": + let struct = newGoogleProtobufStruct(string(message.value)) + result = newJObject() + result["@type"] = %message.typeUrl + result["value"] = toJson(struct) + of "type.googleapis.com/google.protobuf.Value": + let value = newGoogleProtobufValue(string(message.value)) + result = newJObject() + result["@type"] = %message.typeUrl + result["value"] = toJson(value) + of "type.googleapis.com/google.protobuf.ListValue": + let lst = newGoogleProtobufListValue(string(message.value)) + result = newJObject() + result["@type"] = %message.typeUrl + result["value"] = toJson(lst) + of "type.googleapis.com/google.protobuf.Timestamp": + let value = newGoogleProtobufTimestamp(string(message.value)) + result = newJObject() + result["@type"] = %message.typeUrl + result["value"] = toJson(value) + else: + result = newJObject() + result["typeUrl"] = %message.typeUrl + result["value"] = %message.value diff --git a/src/nimpb/wkt/any_pb.nim b/src/nimpb/wkt/any_pb.nim index a452870..aa6f56c 100644 --- a/src/nimpb/wkt/any_pb.nim +++ b/src/nimpb/wkt/any_pb.nim @@ -1,8 +1,11 @@ # Generated by protoc_gen_nim. Do not edit! +import base64 import intsets +import json import nimpb/nimpb +import nimpb/json as nimpb_json type google_protobuf_Any* = ref google_protobuf_AnyObj diff --git a/src/nimpb/wkt/api_pb.nim b/src/nimpb/wkt/api_pb.nim index 21b4a6d..28f5b2b 100644 --- a/src/nimpb/wkt/api_pb.nim +++ b/src/nimpb/wkt/api_pb.nim @@ -1,8 +1,11 @@ # Generated by protoc_gen_nim. Do not edit! +import base64 import intsets +import json import nimpb/nimpb +import nimpb/json as nimpb_json import nimpb/wkt/source_context_pb import nimpb/wkt/type_pb @@ -42,18 +45,21 @@ proc newgoogle_protobuf_Method*(data: string): google_protobuf_Method proc writegoogle_protobuf_Method*(stream: ProtobufStream, message: google_protobuf_Method) proc readgoogle_protobuf_Method*(stream: ProtobufStream): google_protobuf_Method proc sizeOfgoogle_protobuf_Method*(message: google_protobuf_Method): uint64 +proc toJson*(message: google_protobuf_Method): JsonNode proc newgoogle_protobuf_Mixin*(): google_protobuf_Mixin proc newgoogle_protobuf_Mixin*(data: string): google_protobuf_Mixin proc writegoogle_protobuf_Mixin*(stream: ProtobufStream, message: google_protobuf_Mixin) proc readgoogle_protobuf_Mixin*(stream: ProtobufStream): google_protobuf_Mixin proc sizeOfgoogle_protobuf_Mixin*(message: google_protobuf_Mixin): uint64 +proc toJson*(message: google_protobuf_Mixin): JsonNode proc newgoogle_protobuf_Api*(): google_protobuf_Api proc newgoogle_protobuf_Api*(data: string): google_protobuf_Api proc writegoogle_protobuf_Api*(stream: ProtobufStream, message: google_protobuf_Api) proc readgoogle_protobuf_Api*(stream: ProtobufStream): google_protobuf_Api proc sizeOfgoogle_protobuf_Api*(message: google_protobuf_Api): uint64 +proc toJson*(message: google_protobuf_Api): JsonNode proc newgoogle_protobuf_Method*(): google_protobuf_Method = new(result) @@ -265,6 +271,26 @@ proc readgoogle_protobuf_Method*(stream: ProtobufStream): google_protobuf_Method setsyntax(result, readEnum[google_protobuf_Syntax](stream)) else: readUnknownField(stream, tag, result.unknownFields) +proc toJson*(message: google_protobuf_Method): JsonNode = + result = newJObject() + if hasname(message): + result["name"] = %message.name + if hasrequest_type_url(message): + result["requestTypeUrl"] = %message.request_type_url + if hasrequest_streaming(message): + result["requestStreaming"] = %message.request_streaming + if hasresponse_type_url(message): + result["responseTypeUrl"] = %message.response_type_url + if hasresponse_streaming(message): + result["responseStreaming"] = %message.response_streaming + if hasoptions(message): + let arr = newJArray() + for value in message.options: + add(arr, toJson(value)) + result["options"] = arr + if hassyntax(message): + result["syntax"] = %($message.syntax) + proc serialize*(message: google_protobuf_Method): string = let ss = newStringStream() @@ -354,6 +380,13 @@ proc readgoogle_protobuf_Mixin*(stream: ProtobufStream): google_protobuf_Mixin = setroot(result, readString(stream)) else: readUnknownField(stream, tag, result.unknownFields) +proc toJson*(message: google_protobuf_Mixin): JsonNode = + result = newJObject() + if hasname(message): + result["name"] = %message.name + if hasroot(message): + result["root"] = %message.root + proc serialize*(message: google_protobuf_Mixin): string = let ss = newStringStream() @@ -589,6 +622,32 @@ proc readgoogle_protobuf_Api*(stream: ProtobufStream): google_protobuf_Api = setsyntax(result, readEnum[google_protobuf_Syntax](stream)) else: readUnknownField(stream, tag, result.unknownFields) +proc toJson*(message: google_protobuf_Api): JsonNode = + result = newJObject() + if hasname(message): + result["name"] = %message.name + if hasmethods(message): + let arr = newJArray() + for value in message.methods: + add(arr, toJson(value)) + result["methods"] = arr + if hasoptions(message): + let arr = newJArray() + for value in message.options: + add(arr, toJson(value)) + result["options"] = arr + if hasversion(message): + result["version"] = %message.version + if hassource_context(message): + result["sourceContext"] = toJson(message.source_context) + if hasmixins(message): + let arr = newJArray() + for value in message.mixins: + add(arr, toJson(value)) + result["mixins"] = arr + if hassyntax(message): + result["syntax"] = %($message.syntax) + proc serialize*(message: google_protobuf_Api): string = let ss = newStringStream() diff --git a/src/nimpb/wkt/duration_pb.nim b/src/nimpb/wkt/duration_pb.nim index f2b5360..d15aeee 100644 --- a/src/nimpb/wkt/duration_pb.nim +++ b/src/nimpb/wkt/duration_pb.nim @@ -1,8 +1,11 @@ # Generated by protoc_gen_nim. Do not edit! +import base64 import intsets +import json import nimpb/nimpb +import nimpb/json as nimpb_json type google_protobuf_Duration* = ref google_protobuf_DurationObj diff --git a/src/nimpb/wkt/empty_pb.nim b/src/nimpb/wkt/empty_pb.nim index e36260f..c53cb03 100644 --- a/src/nimpb/wkt/empty_pb.nim +++ b/src/nimpb/wkt/empty_pb.nim @@ -1,8 +1,11 @@ # Generated by protoc_gen_nim. Do not edit! +import base64 import intsets +import json import nimpb/nimpb +import nimpb/json as nimpb_json type google_protobuf_Empty* = ref google_protobuf_EmptyObj @@ -15,6 +18,7 @@ proc newgoogle_protobuf_Empty*(data: string): google_protobuf_Empty proc writegoogle_protobuf_Empty*(stream: ProtobufStream, message: google_protobuf_Empty) proc readgoogle_protobuf_Empty*(stream: ProtobufStream): google_protobuf_Empty proc sizeOfgoogle_protobuf_Empty*(message: google_protobuf_Empty): uint64 +proc toJson*(message: google_protobuf_Empty): JsonNode proc newgoogle_protobuf_Empty*(): google_protobuf_Empty = new(result) @@ -39,6 +43,9 @@ proc readgoogle_protobuf_Empty*(stream: ProtobufStream): google_protobuf_Empty = raise newException(InvalidFieldNumberError, "Invalid field number: 0") else: readUnknownField(stream, tag, result.unknownFields) +proc toJson*(message: google_protobuf_Empty): JsonNode = + result = newJObject() + proc serialize*(message: google_protobuf_Empty): string = let ss = newStringStream() diff --git a/src/nimpb/wkt/field_mask_pb.nim b/src/nimpb/wkt/field_mask_pb.nim index 23e125e..e925416 100644 --- a/src/nimpb/wkt/field_mask_pb.nim +++ b/src/nimpb/wkt/field_mask_pb.nim @@ -1,8 +1,11 @@ # Generated by protoc_gen_nim. Do not edit! +import base64 import intsets +import json import nimpb/nimpb +import nimpb/json as nimpb_json type google_protobuf_FieldMask* = ref google_protobuf_FieldMaskObj diff --git a/src/nimpb/wkt/source_context_pb.nim b/src/nimpb/wkt/source_context_pb.nim index 6cc19af..815da98 100644 --- a/src/nimpb/wkt/source_context_pb.nim +++ b/src/nimpb/wkt/source_context_pb.nim @@ -1,8 +1,11 @@ # Generated by protoc_gen_nim. Do not edit! +import base64 import intsets +import json import nimpb/nimpb +import nimpb/json as nimpb_json type google_protobuf_SourceContext* = ref google_protobuf_SourceContextObj @@ -16,6 +19,7 @@ proc newgoogle_protobuf_SourceContext*(data: string): google_protobuf_SourceCont proc writegoogle_protobuf_SourceContext*(stream: ProtobufStream, message: google_protobuf_SourceContext) proc readgoogle_protobuf_SourceContext*(stream: ProtobufStream): google_protobuf_SourceContext proc sizeOfgoogle_protobuf_SourceContext*(message: google_protobuf_SourceContext): uint64 +proc toJson*(message: google_protobuf_SourceContext): JsonNode proc newgoogle_protobuf_SourceContext*(): google_protobuf_SourceContext = new(result) @@ -66,6 +70,11 @@ proc readgoogle_protobuf_SourceContext*(stream: ProtobufStream): google_protobuf setfile_name(result, readString(stream)) else: readUnknownField(stream, tag, result.unknownFields) +proc toJson*(message: google_protobuf_SourceContext): JsonNode = + result = newJObject() + if hasfile_name(message): + result["fileName"] = %message.file_name + proc serialize*(message: google_protobuf_SourceContext): string = let ss = newStringStream() diff --git a/src/nimpb/wkt/struct_pb.nim b/src/nimpb/wkt/struct_pb.nim index 73db617..2a38f6d 100644 --- a/src/nimpb/wkt/struct_pb.nim +++ b/src/nimpb/wkt/struct_pb.nim @@ -1,10 +1,13 @@ # Generated by protoc_gen_nim. Do not edit! +import base64 import intsets +import json import tables export tables import nimpb/nimpb +import nimpb/json as nimpb_json type google_protobuf_NullValue* {.pure.} = enum diff --git a/src/nimpb/wkt/timestamp_pb.nim b/src/nimpb/wkt/timestamp_pb.nim index bddbd55..5f00154 100644 --- a/src/nimpb/wkt/timestamp_pb.nim +++ b/src/nimpb/wkt/timestamp_pb.nim @@ -1,8 +1,11 @@ # Generated by protoc_gen_nim. Do not edit! +import base64 import intsets +import json import nimpb/nimpb +import nimpb/json as nimpb_json type google_protobuf_Timestamp* = ref google_protobuf_TimestampObj diff --git a/src/nimpb/wkt/type_pb.nim b/src/nimpb/wkt/type_pb.nim index 153f257..efb7d26 100644 --- a/src/nimpb/wkt/type_pb.nim +++ b/src/nimpb/wkt/type_pb.nim @@ -1,8 +1,11 @@ # Generated by protoc_gen_nim. Do not edit! +import base64 import intsets +import json import nimpb/nimpb +import nimpb/json as nimpb_json import nimpb/wkt/any_pb import nimpb/wkt/source_context_pb @@ -88,30 +91,35 @@ proc newgoogle_protobuf_Option*(data: string): google_protobuf_Option proc writegoogle_protobuf_Option*(stream: ProtobufStream, message: google_protobuf_Option) proc readgoogle_protobuf_Option*(stream: ProtobufStream): google_protobuf_Option proc sizeOfgoogle_protobuf_Option*(message: google_protobuf_Option): uint64 +proc toJson*(message: google_protobuf_Option): JsonNode proc newgoogle_protobuf_Field*(): google_protobuf_Field proc newgoogle_protobuf_Field*(data: string): google_protobuf_Field proc writegoogle_protobuf_Field*(stream: ProtobufStream, message: google_protobuf_Field) proc readgoogle_protobuf_Field*(stream: ProtobufStream): google_protobuf_Field proc sizeOfgoogle_protobuf_Field*(message: google_protobuf_Field): uint64 +proc toJson*(message: google_protobuf_Field): JsonNode proc newgoogle_protobuf_Type*(): google_protobuf_Type proc newgoogle_protobuf_Type*(data: string): google_protobuf_Type proc writegoogle_protobuf_Type*(stream: ProtobufStream, message: google_protobuf_Type) proc readgoogle_protobuf_Type*(stream: ProtobufStream): google_protobuf_Type proc sizeOfgoogle_protobuf_Type*(message: google_protobuf_Type): uint64 +proc toJson*(message: google_protobuf_Type): JsonNode proc newgoogle_protobuf_EnumValue*(): google_protobuf_EnumValue proc newgoogle_protobuf_EnumValue*(data: string): google_protobuf_EnumValue proc writegoogle_protobuf_EnumValue*(stream: ProtobufStream, message: google_protobuf_EnumValue) proc readgoogle_protobuf_EnumValue*(stream: ProtobufStream): google_protobuf_EnumValue proc sizeOfgoogle_protobuf_EnumValue*(message: google_protobuf_EnumValue): uint64 +proc toJson*(message: google_protobuf_EnumValue): JsonNode proc newgoogle_protobuf_Enum*(): google_protobuf_Enum proc newgoogle_protobuf_Enum*(data: string): google_protobuf_Enum proc writegoogle_protobuf_Enum*(stream: ProtobufStream, message: google_protobuf_Enum) proc readgoogle_protobuf_Enum*(stream: ProtobufStream): google_protobuf_Enum proc sizeOfgoogle_protobuf_Enum*(message: google_protobuf_Enum): uint64 +proc toJson*(message: google_protobuf_Enum): JsonNode proc newgoogle_protobuf_Option*(): google_protobuf_Option = new(result) @@ -189,6 +197,13 @@ proc readgoogle_protobuf_Option*(stream: ProtobufStream): google_protobuf_Option setvalue(result, newgoogle_protobuf_Any(data)) else: readUnknownField(stream, tag, result.unknownFields) +proc toJson*(message: google_protobuf_Option): JsonNode = + result = newJObject() + if hasname(message): + result["name"] = %message.name + if hasvalue(message): + result["value"] = toJson(message.value) + proc serialize*(message: google_protobuf_Option): string = let ss = newStringStream() @@ -491,6 +506,32 @@ proc readgoogle_protobuf_Field*(stream: ProtobufStream): google_protobuf_Field = setdefault_value(result, readString(stream)) else: readUnknownField(stream, tag, result.unknownFields) +proc toJson*(message: google_protobuf_Field): JsonNode = + result = newJObject() + if haskind(message): + result["kind"] = %($message.kind) + if hascardinality(message): + result["cardinality"] = %($message.cardinality) + if hasnumber(message): + result["number"] = %message.number + if hasname(message): + result["name"] = %message.name + if hastype_url(message): + result["typeUrl"] = %message.type_url + if hasoneof_index(message): + result["oneofIndex"] = %message.oneof_index + if haspacked(message): + result["packed"] = %message.packed + if hasoptions(message): + let arr = newJArray() + for value in message.options: + add(arr, toJson(value)) + result["options"] = arr + if hasjson_name(message): + result["jsonName"] = %message.json_name + if hasdefault_value(message): + result["defaultValue"] = %message.default_value + proc serialize*(message: google_protobuf_Field): string = let ss = newStringStream() @@ -699,6 +740,30 @@ proc readgoogle_protobuf_Type*(stream: ProtobufStream): google_protobuf_Type = setsyntax(result, readEnum[google_protobuf_Syntax](stream)) else: readUnknownField(stream, tag, result.unknownFields) +proc toJson*(message: google_protobuf_Type): JsonNode = + result = newJObject() + if hasname(message): + result["name"] = %message.name + if hasfields(message): + let arr = newJArray() + for value in message.fields: + add(arr, toJson(value)) + result["fields"] = arr + if hasoneofs(message): + let arr = newJArray() + for value in message.oneofs: + add(arr, %value) + result["oneofs"] = arr + if hasoptions(message): + let arr = newJArray() + for value in message.options: + add(arr, toJson(value)) + result["options"] = arr + if hassource_context(message): + result["sourceContext"] = toJson(message.source_context) + if hassyntax(message): + result["syntax"] = %($message.syntax) + proc serialize*(message: google_protobuf_Type): string = let ss = newStringStream() @@ -819,6 +884,18 @@ proc readgoogle_protobuf_EnumValue*(stream: ProtobufStream): google_protobuf_Enu addoptions(result, newgoogle_protobuf_Option(data)) else: readUnknownField(stream, tag, result.unknownFields) +proc toJson*(message: google_protobuf_EnumValue): JsonNode = + result = newJObject() + if hasname(message): + result["name"] = %message.name + if hasnumber(message): + result["number"] = %message.number + if hasoptions(message): + let arr = newJArray() + for value in message.options: + add(arr, toJson(value)) + result["options"] = arr + proc serialize*(message: google_protobuf_EnumValue): string = let ss = newStringStream() @@ -997,6 +1074,25 @@ proc readgoogle_protobuf_Enum*(stream: ProtobufStream): google_protobuf_Enum = setsyntax(result, readEnum[google_protobuf_Syntax](stream)) else: readUnknownField(stream, tag, result.unknownFields) +proc toJson*(message: google_protobuf_Enum): JsonNode = + result = newJObject() + if hasname(message): + result["name"] = %message.name + if hasenumvalue(message): + let arr = newJArray() + for value in message.enumvalue: + add(arr, toJson(value)) + result["enumvalue"] = arr + if hasoptions(message): + let arr = newJArray() + for value in message.options: + add(arr, toJson(value)) + result["options"] = arr + if hassource_context(message): + result["sourceContext"] = toJson(message.source_context) + if hassyntax(message): + result["syntax"] = %($message.syntax) + proc serialize*(message: google_protobuf_Enum): string = let ss = newStringStream() diff --git a/src/nimpb/wkt/wrappers_pb.nim b/src/nimpb/wkt/wrappers_pb.nim index 296f5f4..d1b5f80 100644 --- a/src/nimpb/wkt/wrappers_pb.nim +++ b/src/nimpb/wkt/wrappers_pb.nim @@ -1,8 +1,11 @@ # Generated by protoc_gen_nim. Do not edit! +import base64 import intsets +import json import nimpb/nimpb +import nimpb/json as nimpb_json type google_protobuf_DoubleValue* = ref google_protobuf_DoubleValueObj diff --git a/tests/conformance/conformance_nim.nim b/tests/conformance/conformance_nim.nim index 9b30d26..461bc43 100644 --- a/tests/conformance/conformance_nim.nim +++ b/tests/conformance/conformance_nim.nim @@ -1,4 +1,5 @@ import endians +import json import streams import strformat @@ -27,7 +28,13 @@ proc myReadString(s: Stream, size: int): string = raise newException(Exception, "failed to read data") while true: - var requestSize = readInt32Le(inputStream) + var requestSize = 0'i32 + + try: + requestSize = readInt32Le(inputStream) + except: + break + var requestData = myReadString(inputStream, requestSize) let request = newConformance_ConformanceRequest(requestData) @@ -36,19 +43,22 @@ while true: if request.messageType == "protobuf_test_messages.proto2.TestAllTypesProto2": response.skipped = "skipping proto2 tests" - elif request.requestedOutputFormat == conformance_WireFormat.JSON: - response.skipped = "dont know how to output json" elif hasJsonPayload(request): response.skipped = "dont know how to parse json" else: try: let parsed = newprotobuf_test_messages_proto3_TestAllTypesProto3(string(request.protobufPayload)) - let ser = serialize(parsed) - response.protobufPayload = bytes(ser) + if request.requestedOutputFormat == conformance_WireFormat.PROTOBUF: + let ser = serialize(parsed) + response.protobufPayload = bytes(ser) + elif request.requestedOutputFormat == conformance_WireFormat.JSON: + response.jsonPayload = $toJson(parsed) except IOError as exc: response.parse_error = exc.msg except ParseError as exc: response.parse_error = exc.msg + except ValueError as exc: + response.serializeError = exc.msg except Exception as exc: response.runtimeError = exc.msg diff --git a/tests/conformance/failures.txt b/tests/conformance/failures.txt new file mode 100644 index 0000000..5e8f520 --- /dev/null +++ b/tests/conformance/failures.txt @@ -0,0 +1,18 @@ + +CONFORMANCE TEST BEGIN ==================================== + +ERROR, test=Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput: Output was not equivalent to reference message: modified: optional_double: 2.2250738585072014e-308 -> 2.2250738585072009e-308 +. request=protobuf_payload: "a\232\231\231\231\231\231\271?a\377\377\377\377\377\377\357\177a\000\000\000\000\000\000\020\000" requested_output_format: JSON message_type: "protobuf_test_messages.proto3.TestAllTypesProto3", response=json_payload: "{\"optionalDouble\":2.225073858507201e-308}" +ERROR, test=Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput: JSON output we received from test was unparseable. request=protobuf_payload: "\321\002\232\231\231\231\231\231\271?\321\002\377\377\377\377\377\377\357\177\321\002\000\000\000\000\000\000\020\000" requested_output_format: JSON message_type: "protobuf_test_messages.proto3.TestAllTypesProto3", response=json_payload: "{\"repeatedDouble\":[0.1,1.797693134862316e+308,2.225073858507201e-308]}" +WARNING, test=Recommended.FieldMaskPathsDontRoundTrip.JsonOutput: Should have failed to serialize, but didn't. request=protobuf_payload: "\372\022\010\n\006fooBar" requested_output_format: JSON message_type: "protobuf_test_messages.proto3.TestAllTypesProto3", response=json_payload: "{\"optionalFieldMask\":\"fooBar\"}" +WARNING, test=Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput: Should have failed to serialize, but didn't. request=protobuf_payload: "\372\022\013\n\tfoo_3_bar" requested_output_format: JSON message_type: "protobuf_test_messages.proto3.TestAllTypesProto3", response=json_payload: "{\"optionalFieldMask\":\"foo_3_bar\"}" +WARNING, test=Recommended.FieldMaskTooManyUnderscore.JsonOutput: Should have failed to serialize, but didn't. request=protobuf_payload: "\372\022\n\n\010foo__bar" requested_output_format: JSON message_type: "protobuf_test_messages.proto3.TestAllTypesProto3", response=json_payload: "{\"optionalFieldMask\":\"foo__bar\"}" + +These tests failed. If they can't be fixed right now, you can add them to the failure list so the overall suite can succeed. Add them to the failure list by running: + ./update_failure_list.py --add failing_tests.txt + + Required.Proto3.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput + Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput + +CONFORMANCE SUITE FAILED: 249 successes, 563 skipped, 0 expected failures, 2 unexpected failures. + |
