Created
January 24, 2019 12:11
-
-
Save ondrej-kvasnovsky/872dd17eb26f7d5326dcc6874f03041e to your computer and use it in GitHub Desktop.
Struct to JSON in JavaScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright 2017, Google, Inc. | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
/** | |
* @fileoverview Utilities for converting between JSON and goog.protobuf.Struct | |
* proto. | |
*/ | |
'use strict'; | |
function jsonToStructProto(json) { | |
const fields = {}; | |
for (const k in json) { | |
fields[k] = jsonValueToProto(json[k]); | |
} | |
return {fields}; | |
} | |
const JSON_SIMPLE_TYPE_TO_PROTO_KIND_MAP = { | |
[typeof 0]: 'numberValue', | |
[typeof '']: 'stringValue', | |
[typeof false]: 'boolValue', | |
}; | |
const JSON_SIMPLE_VALUE_KINDS = new Set([ | |
'numberValue', | |
'stringValue', | |
'boolValue', | |
]); | |
function jsonValueToProto(value) { | |
const valueProto = {}; | |
if (value === null) { | |
valueProto.kind = 'nullValue'; | |
valueProto.nullValue = 'NULL_VALUE'; | |
} else if (value instanceof Array) { | |
valueProto.kind = 'listValue'; | |
valueProto.listValue = {values: value.map(jsonValueToProto)}; | |
} else if (typeof value === 'object') { | |
valueProto.kind = 'structValue'; | |
valueProto.structValue = jsonToStructProto(value); | |
} else if (typeof value in JSON_SIMPLE_TYPE_TO_PROTO_KIND_MAP) { | |
const kind = JSON_SIMPLE_TYPE_TO_PROTO_KIND_MAP[typeof value]; | |
valueProto.kind = kind; | |
valueProto[kind] = value; | |
} else { | |
console.warn('Unsupported value type ', typeof value); | |
} | |
return valueProto; | |
} | |
function structProtoToJson(proto) { | |
if (!proto || !proto.fields) { | |
return {}; | |
} | |
const json = {}; | |
for (const k in proto.fields) { | |
json[k] = valueProtoToJson(proto.fields[k]); | |
} | |
return json; | |
} | |
function valueProtoToJson(proto) { | |
if (!proto || !proto.kind) { | |
return null; | |
} | |
if (JSON_SIMPLE_VALUE_KINDS.has(proto.kind)) { | |
return proto[proto.kind]; | |
} else if (proto.kind === 'nullValue') { | |
return null; | |
} else if (proto.kind === 'listValue') { | |
if (!proto.listValue || !proto.listValue.values) { | |
console.warn('Invalid JSON list value proto: ', JSON.stringify(proto)); | |
} | |
return proto.listValue.values.map(valueProtoToJson); | |
} else if (proto.kind === 'structValue') { | |
return structProtoToJson(proto.structValue); | |
} else { | |
console.warn('Unsupported JSON value proto kind: ', proto.kind); | |
return null; | |
} | |
} | |
module.exports = { | |
jsonToStructProto, | |
structProtoToJson, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment