@@ -301,36 +301,35 @@ Result<std::unique_ptr<SortOrder>> SortOrderFromJson(const nlohmann::json& json)
301301 return SortOrder::Make (order_id, std::move (sort_fields));
302302}
303303
304- nlohmann::json ToJson (const SchemaField& field) {
304+ Result< nlohmann::json> ToJson (const SchemaField& field) {
305305 nlohmann::json json;
306306 json[kId ] = field.field_id ();
307307 json[kName ] = field.name ();
308308 json[kRequired ] = !field.optional ();
309- json[kType ] = ToJson (*field.type ());
309+ ICEBERG_ASSIGN_OR_RAISE ( json[kType ], ToJson (*field.type () ));
310310 if (!field.doc ().empty ()) {
311311 json[kDoc ] = field.doc ();
312312 }
313- // Defaults are validated to be primitive literals matching the field type, so
314- // single-value serialization cannot fail here.
315313 if (field.initial_default ().has_value ()) {
316- ICEBERG_ASSIGN_OR_THROW (json[kInitialDefault ],
314+ ICEBERG_ASSIGN_OR_RAISE (json[kInitialDefault ],
317315 ToJson (field.initial_default ()->get ()));
318316 }
319317 if (field.write_default ().has_value ()) {
320- ICEBERG_ASSIGN_OR_THROW (json[kWriteDefault ], ToJson (field.write_default ()->get ()));
318+ ICEBERG_ASSIGN_OR_RAISE (json[kWriteDefault ], ToJson (field.write_default ()->get ()));
321319 }
322320 return json;
323321}
324322
325- nlohmann::json ToJson (const Type& type) {
323+ Result< nlohmann::json> ToJson (const Type& type) {
326324 switch (type.type_id ()) {
327325 case TypeId::kStruct : {
328326 const auto & struct_type = internal::checked_cast<const StructType&>(type);
329327 nlohmann::json json;
330328 json[kType ] = kStruct ;
331329 nlohmann::json fields_json = nlohmann::json::array ();
332330 for (const auto & field : struct_type.fields ()) {
333- fields_json.push_back (ToJson (field));
331+ ICEBERG_ASSIGN_OR_RAISE (auto field_json, ToJson (field));
332+ fields_json.push_back (std::move (field_json));
334333 }
335334 json[kFields ] = fields_json;
336335 return json;
@@ -343,7 +342,7 @@ nlohmann::json ToJson(const Type& type) {
343342 const auto & element_field = list_type.fields ().front ();
344343 json[kElementId ] = element_field.field_id ();
345344 json[kElementRequired ] = !element_field.optional ();
346- json[kElement ] = ToJson (*element_field.type ());
345+ ICEBERG_ASSIGN_OR_RAISE ( json[kElement ], ToJson (*element_field.type () ));
347346 return json;
348347 }
349348 case TypeId::kMap : {
@@ -353,12 +352,12 @@ nlohmann::json ToJson(const Type& type) {
353352
354353 const auto & key_field = map_type.key ();
355354 json[kKeyId ] = key_field.field_id ();
356- json[kKey ] = ToJson (*key_field.type ());
355+ ICEBERG_ASSIGN_OR_RAISE ( json[kKey ], ToJson (*key_field.type () ));
357356
358357 const auto & value_field = map_type.value ();
359358 json[kValueId ] = value_field.field_id ();
360359 json[kValueRequired ] = !value_field.optional ();
361- json[kValue ] = ToJson (*value_field.type ());
360+ ICEBERG_ASSIGN_OR_RAISE ( json[kValue ], ToJson (*value_field.type () ));
362361 return json;
363362 }
364363 case TypeId::kBoolean :
@@ -404,8 +403,9 @@ nlohmann::json ToJson(const Type& type) {
404403 std::unreachable ();
405404}
406405
407- nlohmann::json ToJson (const Schema& schema) {
408- nlohmann::json json = ToJson (internal::checked_cast<const Type&>(schema));
406+ Result<nlohmann::json> ToJson (const Schema& schema) {
407+ ICEBERG_ASSIGN_OR_RAISE (nlohmann::json json,
408+ ToJson (internal::checked_cast<const Type&>(schema)));
409409 json[kSchemaId ] = schema.schema_id ();
410410 if (!schema.IdentifierFieldIds ().empty ()) {
411411 json[kIdentifierFieldIds ] = schema.IdentifierFieldIds ();
@@ -414,7 +414,8 @@ nlohmann::json ToJson(const Schema& schema) {
414414}
415415
416416Result<std::string> ToJsonString (const Schema& schema) {
417- return ToJsonString (ToJson (schema));
417+ ICEBERG_ASSIGN_OR_RAISE (auto json, ToJson (schema));
418+ return ToJsonString (json);
418419}
419420
420421nlohmann::json ToJson (const SnapshotRef& ref) {
@@ -956,7 +957,7 @@ Result<EncryptedKey> EncryptedKeyFromJson(const nlohmann::json& json) {
956957 };
957958}
958959
959- nlohmann::json ToJson (const TableMetadata& table_metadata) {
960+ Result< nlohmann::json> ToJson (const TableMetadata& table_metadata) {
960961 nlohmann::json json;
961962
962963 json[kFormatVersion ] = table_metadata.format_version ;
@@ -974,15 +975,22 @@ nlohmann::json ToJson(const TableMetadata& table_metadata) {
974975 if (table_metadata.format_version == 1 ) {
975976 for (const auto & schema : table_metadata.schemas ) {
976977 if (schema->schema_id () == table_metadata.current_schema_id ) {
977- json[kSchema ] = ToJson (*schema);
978+ ICEBERG_ASSIGN_OR_RAISE ( json[kSchema ], ToJson (*schema) );
978979 break ;
979980 }
980981 }
981982 }
982983
983984 // write the current schema ID and schema list
984985 json[kCurrentSchemaId ] = table_metadata.current_schema_id ;
985- json[kSchemas ] = ToJsonList (table_metadata.schemas );
986+ // Schemas can carry fallible default-value serialization, so the shared ToJsonList
987+ // helper (which assumes infallible ToJson) is not used here.
988+ nlohmann::json schemas_json = nlohmann::json::array ();
989+ for (const auto & schema : table_metadata.schemas ) {
990+ ICEBERG_ASSIGN_OR_RAISE (auto schema_json, ToJson (*schema));
991+ schemas_json.push_back (std::move (schema_json));
992+ }
993+ json[kSchemas ] = std::move (schemas_json);
986994
987995 // for older readers, continue writing the default spec as "partition-spec"
988996 if (table_metadata.format_version == 1 ) {
@@ -1032,7 +1040,8 @@ nlohmann::json ToJson(const TableMetadata& table_metadata) {
10321040}
10331041
10341042Result<std::string> ToJsonString (const TableMetadata& table_metadata) {
1035- return ToJsonString (ToJson (table_metadata));
1043+ ICEBERG_ASSIGN_OR_RAISE (auto json, ToJson (table_metadata));
1044+ return ToJsonString (json);
10361045}
10371046
10381047namespace {
@@ -1435,7 +1444,7 @@ Result<Namespace> NamespaceFromJson(const nlohmann::json& json) {
14351444 return ns;
14361445}
14371446
1438- nlohmann::json ToJson (const TableUpdate& update) {
1447+ Result< nlohmann::json> ToJson (const TableUpdate& update) {
14391448 nlohmann::json json;
14401449 switch (update.kind ()) {
14411450 case TableUpdate::Kind::kAssignUUID : {
@@ -1454,7 +1463,7 @@ nlohmann::json ToJson(const TableUpdate& update) {
14541463 const auto & u = internal::checked_cast<const table::AddSchema&>(update);
14551464 json[kAction ] = kActionAddSchema ;
14561465 if (u.schema ()) {
1457- json[kSchema ] = ToJson (*u.schema ());
1466+ ICEBERG_ASSIGN_OR_RAISE ( json[kSchema ], ToJson (*u.schema () ));
14581467 } else {
14591468 json[kSchema ] = nlohmann::json::value_t ::null;
14601469 }
0 commit comments