Skip to content

Commit 0edc3de

Browse files
authored
Merge pull request #182 from Point72/ac/structs_to_json
Add to_json method for structs
2 parents b1b9916 + 46f5759 commit 0edc3de

6 files changed

Lines changed: 921 additions & 5 deletions

File tree

cpp/csp/python/CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ add_library(csptypesimpl
1010
CspTypeFactory.cpp
1111
PyCspEnum.cpp
1212
PyCspType.cpp
13-
PyStruct.cpp)
13+
PyStruct.cpp
14+
PyStructToJson.cpp)
1415
set_target_properties(csptypesimpl PROPERTIES PUBLIC_HEADER "${CSPTYPESIMPL_PUBLIC_HEADERS}")
16+
target_compile_definitions(csptypesimpl PUBLIC RAPIDJSON_HAS_STDSTRING=1)
1517
target_link_libraries(csptypesimpl csp_core csp_types)
1618

1719
set(CSPIMPL_PUBLIC_HEADERS
@@ -36,7 +38,8 @@ set(CSPIMPL_PUBLIC_HEADERS
3638
PyObjectPtr.h
3739
PyOutputAdapterWrapper.h
3840
PyOutputProxy.h
39-
PyConstants.h)
41+
PyConstants.h
42+
PyStructToJson.h)
4043

4144
add_library(cspimpl SHARED
4245
cspimpl.cpp

cpp/csp/python/PyStruct.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <csp/python/InitHelper.h>
44
#include <csp/python/PyObjectPtr.h>
55
#include <csp/python/PyStruct.h>
6+
#include <csp/python/PyStructToJson.h>
7+
68
#include <unordered_set>
79
#include <type_traits>
810

@@ -170,9 +172,9 @@ static PyObject * PyStructMeta_new( PyTypeObject *subtype, PyObject *args, PyObj
170172

171173
/*back reference to the struct type that will be accessible on the csp struct -> meta()
172174
DialectStructMeta will hold a borrowed reference to the type to avoid a circular dep
173-
175+
174176
This is the layout of references between all these types
175-
StructMeta (shared_ptr) <-------- strong ref
177+
StructMeta (shared_ptr) <-------- strong ref
176178
| |
177179
DialectStructMeta ---> weak ref to PyStructMeta ( the PyType )
178180
/\ /\
@@ -859,7 +861,7 @@ PyObject * PyStruct_deepcopy( PyStruct * self )
859861
CSP_BEGIN_METHOD;
860862
//Note that once tp_alloc is called, the object will get added to GC
861863
//deepcopy traversal may kick in a GC collect, so we have to call that first before the PyStruct is created
862-
//of it may traverse a partially consturcted object and crash
864+
//of it may traverse a partially consturcted object and crash
863865
auto deepcopy = self -> struct_ -> deepcopy();
864866
PyObject * pyDeepcopy = self -> ob_type -> tp_alloc( self -> ob_type, 0 );
865867
new ( pyDeepcopy ) PyStruct( deepcopy );
@@ -912,6 +914,30 @@ PyObject * PyStruct_all_fields_set( PyStruct * self )
912914
return toPython( self -> struct_ -> allFieldsSet() );
913915
}
914916

917+
PyObject * PyStruct_to_json( PyStruct * self, PyObject * args, PyObject * kwargs )
918+
{
919+
CSP_BEGIN_METHOD;
920+
921+
// NOTE: Consider grouping customization properties into a dictionary
922+
PyObject * callable = nullptr;
923+
924+
if( PyArg_ParseTuple( args, "O:to_json", &callable ) )
925+
{
926+
if( !PyCallable_Check( callable ) )
927+
{
928+
CSP_THROW( TypeError, "Parameter must be callable" );
929+
}
930+
}
931+
else
932+
{
933+
CSP_THROW( TypeError, "Expected a callable as the argument" );
934+
}
935+
auto struct_ptr = self -> struct_;
936+
auto buffer = structToJson( struct_ptr, callable );
937+
return toPython( buffer );
938+
CSP_RETURN_NULL;
939+
}
940+
915941
static PyMethodDef PyStruct_methods[] = {
916942
{ "copy", (PyCFunction) PyStruct_copy, METH_NOARGS, "make a shallow copy of the struct" },
917943
{ "deepcopy", (PyCFunction) PyStruct_deepcopy, METH_NOARGS, "make a deep copy of the struct" },
@@ -921,6 +947,7 @@ static PyMethodDef PyStruct_methods[] = {
921947
{ "update_from", (PyCFunction) PyStruct_update_from, METH_O, "update from struct. struct must be same type or a derived type. unset fields will be not be copied" },
922948
{ "update", (PyCFunction) PyStruct_update, METH_VARARGS | METH_KEYWORDS, "update from key=val. given fields will be set on struct. other fields will remain as is in struct" },
923949
{ "all_fields_set", (PyCFunction) PyStruct_all_fields_set, METH_NOARGS, "return true if all fields on the struct are set" },
950+
{ "to_json", (PyCFunction) PyStruct_to_json, METH_VARARGS | METH_KEYWORDS, "return a json string of the struct by recursively converting struct members into json format" },
924951
{ NULL}
925952
};
926953

0 commit comments

Comments
 (0)