diff --git a/capnp/capnp.pyx b/capnp/capnp.pyx index 0308992..bd233da 100644 --- a/capnp/capnp.pyx +++ b/capnp/capnp.pyx @@ -8,7 +8,7 @@ cimport cython cimport capnp_cpp as capnp cimport schema_cpp -from capnp_cpp cimport SchemaLoader as C_SchemaLoader, Schema as C_Schema, StructSchema as C_StructSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, DynamicUnion as C_DynamicUnion, fixMaybe, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr +from capnp_cpp cimport SchemaLoader as C_SchemaLoader, Schema as C_Schema, StructSchema as C_StructSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, DynamicUnion as C_DynamicUnion, fixMaybe, fixMaybeUnion, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr from schema_cpp cimport CodeGeneratorRequest as C_CodeGeneratorRequest, Node as C_Node, EnumNode as C_EnumNode from cython.operator cimport dereference as deref @@ -278,7 +278,6 @@ cdef toPython(C_DynamicValue.Builder & self, object parent): else: raise ValueError("Cannot convert type to Python. Type is unhandled by capnproto library") - cdef toPythonByValue(C_DynamicValue.Builder self, object parent): cdef int type = self.getType() if type == capnp.TYPE_BOOL: @@ -309,6 +308,12 @@ cdef toPythonByValue(C_DynamicValue.Builder self, object parent): else: raise ValueError("Cannot convert type to Python. Type is unhandled by capnproto library") +cdef getWhichReader(C_DynamicValue.Reader & val): + return fixMaybe(val.asUnion().which()).getProto().getName().cStr() + +cdef getWhichBuilder(C_DynamicValue.Builder & val): + return fixMaybe(val.asUnion().which()).getProto().getName().cStr() + cdef class _DynamicStructReader: cdef C_DynamicStruct.Reader thisptr cdef public object _parent @@ -326,6 +331,14 @@ cdef class _DynamicStructReader: def _has(self, field): return self.thisptr.has(field) + cpdef which(self): + try: + union = fixMaybeUnion(self.thisptr.getSchema().getUnnamedUnion()) + except: + raise TypeError("This struct has no unnamed enums. You cannot call which on it") + + return getWhichReader(self.thisptr.getByUnion(union)) + cdef class _DynamicStructBuilder: cdef C_DynamicStruct.Builder thisptr cdef public object _parent @@ -381,6 +394,14 @@ cdef class _DynamicStructBuilder: else: return toPythonByValue(self.thisptr.init(field, size), self._parent) + cpdef which(self): + try: + union = fixMaybeUnion(self.thisptr.getSchema().getUnnamedUnion()) + except: + raise TypeError("This struct has no unnamed enums. You cannot call which on it") + + return getWhichBuilder(self.thisptr.getByUnion(union)) + cdef class _DynamicUnionReader: cdef C_DynamicUnion.Reader thisptr cdef public object _parent diff --git a/capnp/capnp_cpp.pxd b/capnp/capnp_cpp.pxd index 7a152b5..c96fa4f 100644 --- a/capnp/capnp_cpp.pxd +++ b/capnp/capnp_cpp.pxd @@ -55,6 +55,7 @@ cdef extern from "capnp/schema.h" namespace " ::capnp": Node.Reader getProto() MemberList getMembers() Member getMemberByName(char * name) + Maybe[StructSchema.Union] getUnnamedUnion() cdef cppclass EnumSchema: cppclass Enumerant: @@ -102,16 +103,21 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp": cdef cppclass DynamicStruct: cppclass Reader: DynamicValueForward.Reader get(char *) except +ValueError + DynamicValueForward.Reader getByUnion'get'(StructSchema.Union member) except +ValueError bint has(char *) except +ValueError + StructSchema getSchema() cppclass Builder: DynamicValueForward.Builder get(char *) except +ValueError + DynamicValueForward.Builder getByUnion'get'(StructSchema.Union member) except +ValueError bint has(char *) except +ValueError void set(char *, DynamicValueForward.Reader&) except +ValueError DynamicValueForward.Builder init(char *, uint size) DynamicValueForward.Builder init(char *) + StructSchema getSchema() cdef extern from "fixMaybe.h": StructSchema.Member fixMaybe(Maybe[StructSchema.Member]) except+ + StructSchema.Union fixMaybeUnion'fixMaybe'(Maybe[StructSchema.Union]) except+ EnumSchema.Enumerant fixMaybe(Maybe[EnumSchema.Enumerant]) except+ cdef extern from "capnp/dynamic.h" namespace " ::capnp": diff --git a/setup.py b/setup.py index c671b5a..55700d3 100644 --- a/setup.py +++ b/setup.py @@ -70,6 +70,6 @@ setup( 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: Implementation :: PyPy' + 'Programming Language :: Python :: Implementation :: PyPy', 'Topic :: Communications'], )