Skip to content

Commit

Permalink
add json serialization customization options (#131)
Browse files Browse the repository at this point in the history
* add json serialization customization options

fixes #123.

* v0.0.47

Co-authored-by: Tate <tate@transcriptic.com>
  • Loading branch information
tatethurston and Tate authored Feb 22, 2022
1 parent 51eb20a commit 2b74bd7
Show file tree
Hide file tree
Showing 18 changed files with 5,094 additions and 29 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v0.0.47

- Add json serialization options. See the README's [configuration section](https://github.com/tatethurston/TwirpScript#configuration-) for more context.

## v0.0.46

This version has 3 breaking changes:
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,19 @@ TypeScript projects will generally want to set this value to match their `rootDi
</td>
<td>javascript | typescript</td>
</tr>
<tr>
<td>json</td>
<td>
JSON serializer options.
`emitFieldsWithDefaultValues` - Fields with default values are omitted by default in proto3 JSON. Setting this to true will serialize fields with their default values.
`useProtoFieldName` - Field names are converted to lowerCamelCase by default in proto3 JSON. Setting this to true will use the proto field name as the JSON key when serializing JSON. Either way, Proto3 JSON parsers are required to accept both the converted lowerCamelCase name and the proto field name.
See https://developers.google.com/protocol-buffers/docs/proto3#json for more context.
</td>
<td>{ emitFieldsWithDefaultValues?: boolean, useProtoFieldName?: boolean }</td>
</tr>
</tbody>
</table>
Expand Down
6 changes: 6 additions & 0 deletions examples/config-json/.twirp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"json": {
"emitFieldsWithDefaultValues": true,
"useProtoFieldName": true
}
}
8 changes: 8 additions & 0 deletions examples/config-json/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# TwirpScript Config JSON Example

## Getting Started

### Running Locally

1. `yarn install`
2. `yarn build`
12 changes: 12 additions & 0 deletions examples/config-json/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "config-json",
"scripts": {
"build": "yarn twirpscript && yarn tsc"
},
"dependencies": {
"twirpscript": "*"
},
"devDependencies": {
"typescript": "^4.3.5"
}
}
123 changes: 123 additions & 0 deletions examples/config-json/src/A.pb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
// Source: src/A.proto

import type { ByteSource } from "twirpscript";
import { BinaryReader, BinaryWriter } from "twirpscript";

//========================================//
// Types //
//========================================//

export interface Foo {
baz: number;
fooBars: string[];
}

//========================================//
// Protobuf Encode / Decode //
//========================================//

export const Foo = {
/**
* Serializes a Foo to protobuf.
*/
encode: function (foo: Partial<Foo>): Uint8Array {
return Foo._writeMessage(foo, new BinaryWriter()).getResultBuffer();
},

/**
* Deserializes a Foo from protobuf.
*/
decode: function (bytes: ByteSource): Foo {
return Foo._readMessage(Foo.initialize(), new BinaryReader(bytes));
},

/**
* Serializes a Foo to JSON.
*/
encodeJSON: function (foo: Partial<Foo>): string {
return JSON.stringify(Foo._writeMessageJSON(foo));
},

/**
* Deserializes a Foo from JSON.
*/
decodeJSON: function (json: string): Foo {
return Foo._readMessageJSON(Foo.initialize(), JSON.parse(json));
},

/**
* Initializes a Foo with all fields set to their default value.
*/
initialize: function (): Foo {
return {
baz: 0,
fooBars: [],
};
},

/**
* @private
*/
_writeMessage: function (
msg: Partial<Foo>,
writer: BinaryWriter
): BinaryWriter {
if (msg.baz) {
writer.writeInt32(1, msg.baz);
}
if (msg.fooBars?.length) {
writer.writeRepeatedString(2, msg.fooBars);
}
return writer;
},

/**
* @private
*/
_writeMessageJSON: function (msg: Partial<Foo>): Record<string, unknown> {
const json: Record<string, unknown> = {};
json.baz = msg.baz;
json.foo_bars = msg.fooBars;
return json;
},

/**
* @private
*/
_readMessage: function (msg: Foo, reader: BinaryReader): Foo {
while (reader.nextField()) {
const field = reader.getFieldNumber();
switch (field) {
case 1: {
msg.baz = reader.readInt32();
break;
}
case 2: {
msg.fooBars.push(reader.readString());
break;
}
default: {
reader.skipField();
break;
}
}
}
return msg;
},

/**
* @private
*/
_readMessageJSON: function (msg: Foo, json: any): Foo {
const baz = json.baz ?? json.baz;
if (baz) {
msg.baz = baz;
}
const fooBars = json.fooBars ?? json.foo_bars;
if (fooBars) {
msg.fooBars = fooBars;
}
return msg;
},
};
6 changes: 6 additions & 0 deletions examples/config-json/src/A.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
syntax = "proto3";

message Foo {
int32 baz = 1;
repeated string foo_bars = 2;
}
13 changes: 13 additions & 0 deletions examples/config-json/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "Node",
"noEmitOnError": false,
"noUnusedLocals": true,
"outDir": "dist",
"rootDir": ".",
"strict": true,
"target": "ES2019"
},
"include": ["src", "out"]
}
Loading

0 comments on commit 2b74bd7

Please sign in to comment.