taepper commented on code in PR #50725:
URL: https://github.com/apache/arrow/pull/50725#discussion_r3692089327


##########
cpp/src/arrow/json/json_writer_internal.cc:
##########
@@ -99,140 +100,98 @@ void JsonWriter::Double(double value) {
 }
 
 Status JsonWriter::WriteValue(sj::value value) {
-  sj::json_type type;
-  if (auto error = value.type().get(type); error != simdjson::SUCCESS) {
-    return Status::Invalid(simdjson::error_message(error));
-  }
+  return internal::VisitJsonValue(
+      value,
 
-  switch (type) {
-    case sj::json_type::object: {
-      StartObject();
+      [&](sj::object object) -> Status {
+        StartObject();
 
-      sj::object object;
-      if (auto error = value.get_object().get(object); error != 
simdjson::SUCCESS) {
-        return Status::Invalid(simdjson::error_message(error));
-      }
+        for (auto field : object) {
+          ARROW_ASSIGN_OR_RAISE(
+              auto key, internal::GetSimdjsonResult(field.unescaped_key(),
+                                                    "Failed to get object key: 
"));
 
-      for (auto field : object) {
-        std::string_view key;
-        if (auto error = field.unescaped_key().get(key); error != 
simdjson::SUCCESS) {
-          return Status::Invalid(simdjson::error_message(error));
-        }
+          Key(key);
 
-        Key(key);
+          ARROW_ASSIGN_OR_RAISE(
+              auto field_value,
+              internal::GetSimdjsonResult(field.value(), "Failed to get object 
value: "));
 
-        sj::value field_value;
-        if (auto error = field.value().get(field_value); error != 
simdjson::SUCCESS) {
-          return Status::Invalid(simdjson::error_message(error));
+          RETURN_NOT_OK(WriteValue(field_value));
         }
 
-        RETURN_NOT_OK(WriteValue(field_value));
-      }
-
-      EndObject();
-      break;
-    }
+        EndObject();
+        return Status::OK();
+      },
 
-    case sj::json_type::array: {
-      StartArray();
+      [&](sj::array array) -> Status {
+        StartArray();
 
-      sj::array array;
-      if (auto error = value.get_array().get(array); error != 
simdjson::SUCCESS) {
-        return Status::Invalid(simdjson::error_message(error));
-      }
+        for (auto element : array) {
+          ARROW_ASSIGN_OR_RAISE(
+              auto element_value,
+              internal::GetSimdjsonResult(element, "Failed to iterate JSON 
array: "));
 
-      for (auto element : array) {
-        sj::value element_value;
-        if (auto error = element.get(element_value); error != 
simdjson::SUCCESS) {
-          return Status::Invalid(simdjson::error_message(error));
+          RETURN_NOT_OK(WriteValue(element_value));
         }
 
-        RETURN_NOT_OK(WriteValue(element_value));
-      }
+        EndArray();
+        return Status::OK();
+      },
+
+      [&](std::string_view string_value) -> Status {
+        String(string_value);
+        return Status::OK();
+      },
+
+      [&](bool bool_value) -> Status {
+        Bool(bool_value);
+        return Status::OK();
+      },
+
+      [&]() -> Status {
+        Null();
+        return Status::OK();
+      },
+
+      [&](sj::value number_value) -> Status {

Review Comment:
   Ah, that is a rather annoying problem, I see. As this will be the only user 
of the library-function, we cannot see how good a solution will fit more 
general usages.
   
   I see two options:
   - Provide another `BigIntegerFn` to the visitor
   - Move the switch on `number_type` also to the visitor and provide all four 
call-backs {`DoubleFn`,`Int64Fn`,`Uint64Fn`,`BigIntegerFn`}, dropping the 
argument `NumberFn`, instead. This would correspond to the `number_type` enum 
in `simdjson`.
   
   ```
   enum class number_type {
       floating_point_number=1, /// a binary64 number
       signed_integer,          /// a signed integer that fits in a 64-bit word 
using two's complement
       unsigned_integer,        /// a positive integer larger or equal to 1<<63
       big_integer              /// a big integer that does not fit in a 64-bit 
word
   };
   ```
   
   If all options of `number_type` could fit into the `number`-struct's 
representation this would not be a problem, but I guess this has been done 
because implementations that want to error on `big_integer` would need to pay a 
performance cost otherwise.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to