@@ -80,31 +80,44 @@ namespace daw {
8080
8181 struct obj_info_t {
8282 std::string name;
83+ bool is_array;
8384 std::map<std::string, val_info_t > members;
85+
86+ obj_info_t ( ):
87+ name{ },
88+ is_array{ false },
89+ members{ } { }
8490 }; // obj_info_t
8591
92+ auto unknown_count ( ) noexcept {
93+ static size_t result = 0 ;
94+ return result++;
95+ }
96+
97+ auto unknown_name ( ) noexcept {
98+ return " unknown_" + std::to_string ( unknown_count ( ) );
99+ }
100+
101+ void parse_json_array ( boost::string_view cur_name, daw::json::impl::value_t const & cur_item, std::unordered_map<std::string, obj_info_t > & obj_info );
86102
87- void obj_to_string ( boost::string_view cur_name, daw::json::impl::object_value const & cur_item, std::unordered_map<std::string, obj_info_t > & obj_info ) {
103+ void parse_json_object ( boost::string_view cur_name, daw::json::impl::object_value const & cur_item, std::unordered_map<std::string, obj_info_t > & obj_info ) {
88104 using daw::json::impl::value_t ;
89105
90106 obj_info_t cur_obj;
91107 cur_obj.name = cur_name.to_string ( );
92108 if ( cur_obj.name .empty ( ) ) {
93- static size_t unknown_count = 0 ;
94- cur_obj.name = " unknown_" + std::to_string ( unknown_count++ );
109+ cur_obj.name = unknown_name ( );
95110 }
96- std::vector<std::string> sub_objects;
97- std::vector<std::string> sub_arrays;
98111 for ( auto const & member: cur_item.container ( ) ) {
99112 val_info_t val_info;
100113 val_info.name = member.first .to_string ( );
101114 val_info.type = member.second .type ( );
102115 cur_obj.members [val_info.name ] = val_info;
103116
104117 if ( val_info.type == value_t ::value_types::object ) {
105- obj_to_string ( val_info.name , member.second .get_object ( ), obj_info );
118+ parse_json_object ( val_info.name , member.second .get_object ( ), obj_info );
106119 } else if ( val_info.type == value_t ::value_types::array ) {
107- sub_arrays. push_back ( val_info.name );
120+ parse_json_array ( val_info.name , member. second , obj_info );
108121 }
109122
110123 }
@@ -114,10 +127,42 @@ namespace daw {
114127 obj_info[cur_obj.name ].members [member.first ] = member.second ;
115128 }
116129 }
117-
118- std::unordered_map<std::string, obj_info_t > obj_to_string ( daw::json::impl::value_t const & json_obj ) {
130+
131+ void parse_json_array ( boost::string_view cur_name, daw::json::impl::value_t const & cur_item, std::unordered_map<std::string, obj_info_t > & obj_info ) {
132+ using daw::json::impl::value_t ;
133+ obj_info_t cur_obj;
134+ cur_obj.is_array = true ;
135+ cur_obj.name = cur_name.to_string ( );
136+ if ( cur_obj.name .empty ( ) ) {
137+ cur_obj.name = unknown_name ( );
138+ }
139+ val_info_t val_info;
140+ val_info.name = " element_" + cur_obj.name ;
141+ auto const & arry = cur_item.get_array ( );
142+ val_info.type = arry.front ( ).type ( );
143+ if ( val_info.type == value_t ::value_types::array ) {
144+ for ( auto const & item: arry ) {
145+ parse_json_array ( val_info.name , item, obj_info );
146+ }
147+ } else if ( val_info.type == value_t ::value_types::object ) {
148+ for ( auto const & item: arry ) {
149+ parse_json_object ( val_info.name , item.get_object ( ), obj_info );
150+ }
151+ }
152+ cur_obj.members [val_info.name ] = val_info;
153+ obj_info[cur_obj.name ] = cur_obj;
154+ }
155+
156+ std::unordered_map<std::string, obj_info_t > parse_json_object ( daw::json::impl::value_t const & json_obj ) {
119157 std::unordered_map<std::string, obj_info_t > result;
120- obj_to_string ( " root_type" , json_obj.get_object ( ), result );
158+ if ( json_obj.type ( ) == daw::json::impl::value_t ::value_types::object ) {
159+ parse_json_object ( " root_type" , json_obj.get_object ( ), result );
160+ } else if ( json_obj.type ( ) == daw::json::impl::value_t ::value_types::array ) {
161+ parse_json_array ( " root_type" , json_obj, result );
162+ } else {
163+ std::cerr << " Root object must either be an array or object and not a bare json value(e.g. integer, real, boolean...)" ;
164+ exit ( EXIT_FAILURE );
165+ }
121166 return result;
122167 }
123168
@@ -170,26 +215,34 @@ namespace daw {
170215 auto const & cur_obj = obj_info_item.second ;
171216 auto const obj_type = cur_obj.name + " _t" ;
172217
173- ss << " struct " << cur_obj. name ;
218+ ss << " struct " << obj_type ;
174219 if ( config.enable_jsonlink ) {
175220 ss << " : public daw::json::JsonLink<" << obj_type << " >" ;
176221 }
177- ss << " {\n " ;
222+ ss << " {\n\n " ;
178223 for ( auto const & item: cur_obj.members ) {
179224 auto const & member = item.second ;
180225 auto const member_type = type_to_string ( member.name , member.type );
181226 ss << " \t " ;
182227 if ( member.is_optional ) {
183- ss << " boost::optional<" << member_type << " >" ;
184- } else {
185- ss << member_type;
228+ ss << " boost::optional<" ;
229+ }
230+ if ( cur_obj.is_array ) {
231+ ss << " std::vector<" ;
186232 }
187- ss << " " << member.name << " ;\n\n " ;
233+ ss << member_type;
234+ if ( cur_obj.is_array ) {
235+ ss << " >" ;
236+ }
237+ if ( member.is_optional ) {
238+ ss << " >" ;
239+ }
240+ ss << " " << member.name << " ;\n " ;
188241 }
189242 if ( config.enable_jsonlink ) {
190243 // Default Constructor
191244 {
192- ss << " \t " << obj_type << " ( ):\n " ;
245+ ss << " \n\ t " << obj_type << " ( ):\n " ;
193246 ss << " \t\t\t daw::json::JsonLink<" << obj_type << " >{ }" ;
194247 for ( auto const & member: cur_obj.members ) {
195248 ss << " ,\n\t\t\t " << member.first << " { }" ;
@@ -223,7 +276,13 @@ namespace daw {
223276 ss << " \t void set_links( ) {" ;
224277 for ( auto const & item: cur_obj.members ) {
225278 auto const & member = item.second ;
226- ss << " \n\t\t link_" << type_to_jsonstring ( member.type ) << " ( \" " << member.name << " \" , " << member.name << " );" ;
279+ ss << " \n\t\t link_" ;
280+ if ( cur_obj.is_array ) {
281+ ss << " array" ;
282+ } else {
283+ ss << type_to_jsonstring ( member.type );
284+ }
285+ ss << " ( \" " << member.name << " \" , " << member.name << " );" ;
227286 }
228287 ss << " \n\t }\n " ;
229288 }
@@ -242,7 +301,7 @@ namespace daw {
242301
243302 std::string generate_cpp ( boost::string_view json_string, config_t const & config ) {
244303 auto json_obj = daw::json::parse_json ( json_string );
245- auto obj_info = obj_to_string ( json_obj );
304+ auto obj_info = parse_json_object ( json_obj );
246305 std::string result = generate_code ( obj_info, config );
247306
248307 return result;
0 commit comments