Skip to content

Instantly share code, notes, and snippets.

@tvdstaaij
Last active June 30, 2016 14:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tvdstaaij/044b3f4fdbe6ffcf6bec to your computer and use it in GitHub Desktop.
Save tvdstaaij/044b3f4fdbe6ffcf6bec to your computer and use it in GitHub Desktop.
Convert ProtoBuf.js enum values to strings using reflection
var _ = require('lodash');
function stringifyEnums(message) {
_.forEach(message.$type.children, function(child) {
var type = _.get(child, 'element.resolvedType', null);
if (type && type.className === 'Enum' && type.children) {
var metaValue = _.find(type.children, {
id: message[child.name]
});
if (metaValue && metaValue.name)
// Alternatively you can do something like:
// message[child.name + '_string'] = metaValue.name;
// To get access to both the raw value and the string.
message[child.name] = metaValue.name;
}
});
return message;
}
// stringifyEnums only works for direct children of one message.
// This function handles enums in submessages as well.
function stringifyEnumsRecursive(message) {
message = stringifyEnums(message);
_.forEach(message, function(subMessage, key) {
if (_.isObject(subMessage) && subMessage.$type)
message[key] = stringifyEnumsRecursive(message[key]);
});
return message;
}
module.exports = {
stringifyEnums: stringifyEnums,
stringifyEnumsRecursive: stringifyEnumsRecursive
};
@tobilg
Copy link

tobilg commented Jun 7, 2016

Thanks, but this doesn't objects in sub-arrays IMHO. Is there an easy solution?

@timCF
Copy link

timCF commented Jun 30, 2016

this should work, bro

utils.coffee

lodash = require('lodash')
module.exports =
    stringifyEnums: (message) ->
        if message.$type
            lodash.forEach(message.$type.children, (child) ->
                type = lodash.get(child, 'element.resolvedType', null)
                if (type and (type.className == 'Enum') and type.children)
                    metaValue = lodash.find(type.children, { id: message[child.name] })
                    if (metaValue and metaValue.name)
                        message[child.name] = metaValue.name)
        message
    stringifyEnumsRecursive: (message) ->
        utils = @
        message = utils.stringifyEnums(message)
        lodash.forEach(message, (subMessage, key) ->
            if (lodash.isObject(subMessage) and subMessage.$type)
                message[key] = utils.stringifyEnumsRecursive(message[key])
            else if (Object.prototype.toString.call(subMessage) == "[object Array]")
                message[key] = subMessage.map((el) -> utils.stringifyEnumsRecursive(el)))
        message

@timCF
Copy link

timCF commented Jun 30, 2016

or better go this way without lodash

utils.coffee

module.exports =
    stringifyEnums: (message) ->
        utils = @
        if (message and message.$type and message.$type.children)
            message.$type.children.forEach((child) ->
                if (message[child.name] and child.element.resolvedType)
                    switch child.element.resolvedType.className
                        when 'Enum'
                            dict = child.element.resolvedType.children.reduce(((acc, {id: id, name: name}) -> acc[id] = name ; acc), {})
                            if child.repeated
                                message[child.name] = message[child.name].map((el) -> dict[el])
                            else
                                message[child.name] = dict[message[child.name]]
                        when 'Message'
                            if child.repeated
                                message[child.name] = message[child.name].map((el) -> utils.stringifyEnums(el))
                            else
                                message[child.name] = utils.stringifyEnums(message[child.name]))
        message

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment