diff --git a/capnp/capnp.pyx b/capnp/capnp.pyx index e334f7e..23a4458 100644 --- a/capnp/capnp.pyx +++ b/capnp/capnp.pyx @@ -568,7 +568,15 @@ import collections as _collections cdef _from_dict_helper(msg, field, d): d_type = type(d) if d_type is dict: - sub_msg = getattr(msg, field) + try: + sub_msg = getattr(msg, field) + except Exception as e: + str_error = str(e) + if 'expected isSetInUnion(field)' in str_error: + msg.init(field) + sub_msg = getattr(msg, field) + else: + raise for key, val in d.iteritems(): if key != 'which': _from_dict_helper(sub_msg, key, val) @@ -584,6 +592,7 @@ cdef _from_dict_helper(msg, field, d): else: setattr(msg, field, d) + cdef _from_dict(msg, d): for key, val in d.iteritems(): if key != 'which': diff --git a/scripts/capnp-json.py b/scripts/capnp-json.py new file mode 100644 index 0000000..ec4eb08 --- /dev/null +++ b/scripts/capnp-json.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +import argparse +import sys +import json +import capnp + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument("command") + parser.add_argument("schema_file") + parser.add_argument("struct_name") + + return parser.parse_args() + +def encode(schema_file, struct_name): + schema = capnp.load(schema_file) + + struct_schema = getattr(schema, struct_name) + + struct_dict = json.load(sys.stdin) + struct = struct_schema.from_dict(struct_dict) + + struct.write(sys.stdout) + +def decode(schema_file, struct_name): + schema = capnp.load(schema_file) + + struct_schema = getattr(schema, struct_name) + struct = struct_schema.read(sys.stdin) + + json.dump(struct.to_dict(), sys.stdout) + +def main(): + args = parse_args() + + command = args.command + kwargs = vars(args) + del kwargs['command'] + + globals()[command](**kwargs) # hacky way to get defined functions, and call function with name=command + +main() \ No newline at end of file