I was going to put this as a comment, but maybe it belongs as an answer:
For what it's worth, ArduinoJSON seems to be able to deserialize directly from a stream, i.e. Serial, which may obviate the question as asked. Presumably it knows where to stop deserializing, because it knows when it has received an entire JSON object; being a proper JSON parser, it can probably work this out better than you can without, you know, writing a JSON parser.
The following was just thrown together, now the author is here you should probably just follow their direction, but here's the code anyway:
#include <ArduinoJson.h>
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
Serial.setTimeout(30000);
}
void print_transmission_counter( {
static unsigned long received_object_counter;
Serial.println(F("\n\n\n\n"));
for (int i = 0; i < 30; ++i) {
Serial.write('-');
}
Serial.write('[');
Serial.print(received_object_counter++);
Serial.println(']');
}
void loop() {
static StaticJsonDocument<256> json_doc;
static bool led_state;
print_transmission_counter();
const auto deser_err = deserializeJson(json_doc, Serial);
if (deser_err) {
Serial.print(F("Failed to deserialize, reason: \""));
Serial.print(deser_err.c_str());
Serial.println('"');
} else {
Serial.print(F("Recevied valid json document with "));
Serial.print(json_doc.size());
Serial.println(F(" elements."));
Serial.println(F("Pretty printed back at you:"));
serializeJsonPretty(json_doc, Serial);
Serial.println();
}
// Just give some visual indication that the loop is progressing
led_state = !led_state;
digitalWrite(LED_BUILTIN, led_state);
}
// vim:sw=2:ts=2:et:nowrap:ft=cpp: