public static <T> byte[] write(Writer<T> writer, T value) {
    byte[] result = new byte[writer.sizeInBytes(value)];
    WriteBuffer b = WriteBuffer.wrap(result);
    try {
      writer.write(value, b);
    } catch (RuntimeException e) {
      int lengthWritten = result.length;
      for (int i = 0; i < result.length; i++) {
        if (result[i] == 0) {
          lengthWritten = i;
          break;
        }
      }

      // Don't use value directly in the message, as its toString might be implemented using this
      // method. If that's the case, we'd stack overflow. Instead, emit what we've written so far.
      String message =
          format(
              "Bug found using %s to write %s as json. Wrote %s/%s bytes: %s",
              writer.getClass().getSimpleName(),
              value.getClass().getSimpleName(),
              lengthWritten,
              result.length,
              new String(result, 0, lengthWritten, UTF_8));
      throw Platform.get().assertionError(message, e);
    }
    return result;
  }
@Test void doesntStackOverflowOnToBufferWriterBug_Overflow() {
    // pretend there was a bug calculating size, ex it calculated incorrectly as to small
    class FooWriter implements WriteBuffer.Writer {
      @Override public int sizeInBytes(Object value) {
        return 2;
      }

      @Override public void write(Object value, WriteBuffer buffer) {
        buffer.writeByte('a');
        buffer.writeByte('b');
        buffer.writeByte('c'); // wrote larger than size!
      }
    }

    class Foo {
      @Override public String toString() {
        return new String(JsonWriter.write(new FooWriter(), this), UTF_8);
      }
    }

    Foo foo = new Foo();
    assertThatThrownBy(foo::toString)
        .isInstanceOf(AssertionError.class)
        .hasMessage("Bug found using FooWriter to write Foo as json. Wrote 2/2 bytes: ab");
  }