mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-08 05:27:14 +09:00
AK+Everywhere: Convert JSON value serialization to String
This removes the use of StringBuilder::OutputType (which was ByteString, and only used by the JSON classes). And it removes the StringBuilder template parameter from the serialization methods; this was only ever used with StringBuilder, so a template is pretty overkill here.
This commit is contained in:
parent
2c03de60da
commit
fe2dff4944
Notes:
github-actions[bot]
2025-02-21 00:28:53 +00:00
Author: https://github.com/trflynn89
Commit: fe2dff4944
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3631
Reviewed-by: https://github.com/awesomekling ✅
15 changed files with 98 additions and 95 deletions
|
@ -13,6 +13,7 @@ set(SOURCES
|
||||||
Format.cpp
|
Format.cpp
|
||||||
GenericLexer.cpp
|
GenericLexer.cpp
|
||||||
Hex.cpp
|
Hex.cpp
|
||||||
|
JsonArray.cpp
|
||||||
JsonObject.cpp
|
JsonObject.cpp
|
||||||
JsonParser.cpp
|
JsonParser.cpp
|
||||||
JsonValue.cpp
|
JsonValue.cpp
|
||||||
|
|
30
AK/JsonArray.cpp
Normal file
30
AK/JsonArray.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <AK/JsonArray.h>
|
||||||
|
#include <AK/JsonArraySerializer.h>
|
||||||
|
#include <AK/StringBuilder.h>
|
||||||
|
|
||||||
|
namespace AK {
|
||||||
|
|
||||||
|
String JsonArray::serialized() const
|
||||||
|
{
|
||||||
|
StringBuilder builder;
|
||||||
|
serialize(builder);
|
||||||
|
|
||||||
|
return MUST(builder.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonArray::serialize(StringBuilder& builder) const
|
||||||
|
{
|
||||||
|
auto serializer = MUST(JsonArraySerializer<>::try_create(builder));
|
||||||
|
for_each([&](auto const& value) {
|
||||||
|
MUST(serializer.add(value));
|
||||||
|
});
|
||||||
|
MUST(serializer.finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
#include <AK/Concepts.h>
|
#include <AK/Concepts.h>
|
||||||
#include <AK/Error.h>
|
#include <AK/Error.h>
|
||||||
#include <AK/JsonArraySerializer.h>
|
|
||||||
#include <AK/JsonValue.h>
|
#include <AK/JsonValue.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
namespace AK {
|
namespace AK {
|
||||||
|
@ -72,11 +72,8 @@ public:
|
||||||
ErrorOr<void> append(JsonValue value) { return m_values.try_append(move(value)); }
|
ErrorOr<void> append(JsonValue value) { return m_values.try_append(move(value)); }
|
||||||
void set(size_t index, JsonValue value) { m_values.at(index) = move(value); }
|
void set(size_t index, JsonValue value) { m_values.at(index) = move(value); }
|
||||||
|
|
||||||
template<typename Builder>
|
String serialized() const;
|
||||||
typename Builder::OutputType serialized() const;
|
void serialize(StringBuilder&) const;
|
||||||
|
|
||||||
template<typename Builder>
|
|
||||||
void serialize(Builder&) const;
|
|
||||||
|
|
||||||
template<typename Callback>
|
template<typename Callback>
|
||||||
void for_each(Callback callback)
|
void for_each(Callback callback)
|
||||||
|
@ -118,22 +115,6 @@ private:
|
||||||
Vector<JsonValue> m_values;
|
Vector<JsonValue> m_values;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Builder>
|
|
||||||
inline void JsonArray::serialize(Builder& builder) const
|
|
||||||
{
|
|
||||||
auto serializer = MUST(JsonArraySerializer<>::try_create(builder));
|
|
||||||
for_each([&](auto& value) { MUST(serializer.add(value)); });
|
|
||||||
MUST(serializer.finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Builder>
|
|
||||||
inline typename Builder::OutputType JsonArray::serialized() const
|
|
||||||
{
|
|
||||||
Builder builder;
|
|
||||||
serialize(builder);
|
|
||||||
return builder.to_byte_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USING_AK_GLOBALLY
|
#if USING_AK_GLOBALLY
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "JsonObject.h"
|
#include <AK/JsonObject.h>
|
||||||
|
#include <AK/JsonObjectSerializer.h>
|
||||||
|
#include <AK/StringBuilder.h>
|
||||||
|
|
||||||
namespace AK {
|
namespace AK {
|
||||||
|
|
||||||
|
@ -275,4 +277,21 @@ bool JsonObject::remove(StringView key)
|
||||||
return m_members.remove(key);
|
return m_members.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String JsonObject::serialized() const
|
||||||
|
{
|
||||||
|
StringBuilder builder;
|
||||||
|
serialize(builder);
|
||||||
|
|
||||||
|
return MUST(builder.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonObject::serialize(StringBuilder& builder) const
|
||||||
|
{
|
||||||
|
auto serializer = MUST(JsonObjectSerializer<>::try_create(builder));
|
||||||
|
for_each_member([&](auto& key, auto& value) {
|
||||||
|
MUST(serializer.add(key, value));
|
||||||
|
});
|
||||||
|
MUST(serializer.finish());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/ByteString.h>
|
|
||||||
#include <AK/Concepts.h>
|
#include <AK/Concepts.h>
|
||||||
#include <AK/Error.h>
|
#include <AK/Error.h>
|
||||||
#include <AK/HashMap.h>
|
#include <AK/HashMap.h>
|
||||||
#include <AK/JsonArray.h>
|
#include <AK/JsonArray.h>
|
||||||
#include <AK/JsonObjectSerializer.h>
|
|
||||||
#include <AK/JsonValue.h>
|
#include <AK/JsonValue.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
|
|
||||||
|
@ -107,59 +105,13 @@ public:
|
||||||
|
|
||||||
bool remove(StringView key);
|
bool remove(StringView key);
|
||||||
|
|
||||||
template<typename Builder>
|
String serialized() const;
|
||||||
typename Builder::OutputType serialized() const;
|
void serialize(StringBuilder&) const;
|
||||||
|
|
||||||
template<typename Builder>
|
|
||||||
void serialize(Builder&) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OrderedHashMap<String, JsonValue> m_members;
|
OrderedHashMap<String, JsonValue> m_members;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Builder>
|
|
||||||
inline void JsonObject::serialize(Builder& builder) const
|
|
||||||
{
|
|
||||||
auto serializer = MUST(JsonObjectSerializer<>::try_create(builder));
|
|
||||||
for_each_member([&](auto& key, auto& value) {
|
|
||||||
MUST(serializer.add(key, value));
|
|
||||||
});
|
|
||||||
MUST(serializer.finish());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Builder>
|
|
||||||
inline typename Builder::OutputType JsonObject::serialized() const
|
|
||||||
{
|
|
||||||
Builder builder;
|
|
||||||
serialize(builder);
|
|
||||||
return builder.to_byte_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Builder>
|
|
||||||
inline void JsonValue::serialize(Builder& builder) const
|
|
||||||
{
|
|
||||||
m_value.visit(
|
|
||||||
[&](Empty const&) { builder.append("null"sv); },
|
|
||||||
[&](bool const& value) { builder.append(value ? "true"sv : "false"sv); },
|
|
||||||
[&](Arithmetic auto const& value) { builder.appendff("{}", value); },
|
|
||||||
[&](String const& value) {
|
|
||||||
builder.append('\"');
|
|
||||||
builder.append_escaped_for_json(value.bytes());
|
|
||||||
builder.append('\"');
|
|
||||||
},
|
|
||||||
[&](auto const& array_or_object) {
|
|
||||||
array_or_object->serialize(builder);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Builder>
|
|
||||||
inline typename Builder::OutputType JsonValue::serialized() const
|
|
||||||
{
|
|
||||||
Builder builder;
|
|
||||||
serialize(builder);
|
|
||||||
return builder.to_byte_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USING_AK_GLOBALLY
|
#if USING_AK_GLOBALLY
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <AK/JsonObject.h>
|
#include <AK/JsonObject.h>
|
||||||
#include <AK/JsonParser.h>
|
#include <AK/JsonParser.h>
|
||||||
#include <AK/JsonValue.h>
|
#include <AK/JsonValue.h>
|
||||||
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
|
|
||||||
namespace AK {
|
namespace AK {
|
||||||
|
@ -192,4 +193,28 @@ ErrorOr<JsonValue> JsonValue::from_string(StringView input)
|
||||||
return JsonParser(input).parse();
|
return JsonParser(input).parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String JsonValue::serialized() const
|
||||||
|
{
|
||||||
|
StringBuilder builder;
|
||||||
|
serialize(builder);
|
||||||
|
|
||||||
|
return MUST(builder.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
void JsonValue::serialize(StringBuilder& builder) const
|
||||||
|
{
|
||||||
|
m_value.visit(
|
||||||
|
[&](Empty const&) { builder.append("null"sv); },
|
||||||
|
[&](bool const& value) { builder.append(value ? "true"sv : "false"sv); },
|
||||||
|
[&](Arithmetic auto const& value) { builder.appendff("{}", value); },
|
||||||
|
[&](String const& value) {
|
||||||
|
builder.append('\"');
|
||||||
|
builder.append_escaped_for_json(value.bytes());
|
||||||
|
builder.append('\"');
|
||||||
|
},
|
||||||
|
[&](auto const& array_or_object) {
|
||||||
|
array_or_object->serialize(builder);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <AK/NonnullOwnPtr.h>
|
#include <AK/NonnullOwnPtr.h>
|
||||||
#include <AK/Optional.h>
|
#include <AK/Optional.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/StringBuilder.h>
|
|
||||||
|
|
||||||
namespace AK {
|
namespace AK {
|
||||||
|
|
||||||
|
@ -77,10 +76,8 @@ public:
|
||||||
JsonValue& operator=(JsonArray&&);
|
JsonValue& operator=(JsonArray&&);
|
||||||
JsonValue& operator=(JsonObject&&);
|
JsonValue& operator=(JsonObject&&);
|
||||||
|
|
||||||
template<typename Builder>
|
String serialized() const;
|
||||||
typename Builder::OutputType serialized() const;
|
void serialize(StringBuilder&) const;
|
||||||
template<typename Builder>
|
|
||||||
void serialize(Builder&) const;
|
|
||||||
|
|
||||||
Optional<int> get_int() const { return get_integer<int>(); }
|
Optional<int> get_int() const { return get_integer<int>(); }
|
||||||
Optional<i32> get_i32() const { return get_integer<i32>(); }
|
Optional<i32> get_i32() const { return get_integer<i32>(); }
|
||||||
|
@ -224,7 +221,7 @@ template<>
|
||||||
struct Formatter<JsonValue> : Formatter<StringView> {
|
struct Formatter<JsonValue> : Formatter<StringView> {
|
||||||
ErrorOr<void> format(FormatBuilder& builder, JsonValue const& value)
|
ErrorOr<void> format(FormatBuilder& builder, JsonValue const& value)
|
||||||
{
|
{
|
||||||
return Formatter<StringView>::format(builder, value.serialized<StringBuilder>());
|
return Formatter<StringView>::format(builder, value.serialized());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ public:
|
||||||
static constexpr size_t inline_capacity = 256;
|
static constexpr size_t inline_capacity = 256;
|
||||||
|
|
||||||
using Buffer = Detail::ByteBuffer<inline_capacity>;
|
using Buffer = Detail::ByteBuffer<inline_capacity>;
|
||||||
using OutputType = ByteString;
|
|
||||||
|
|
||||||
static ErrorOr<StringBuilder> create(size_t initial_capacity = inline_capacity);
|
static ErrorOr<StringBuilder> create(size_t initial_capacity = inline_capacity);
|
||||||
|
|
||||||
|
|
|
@ -754,7 +754,7 @@ void ArgsParser::autocomplete(FILE* file, StringView program_name, ReadonlySpan<
|
||||||
object.set("invariant_offset"sv, has_invariant ? option_to_complete.length() : 0u);
|
object.set("invariant_offset"sv, has_invariant ? option_to_complete.length() : 0u);
|
||||||
object.set("display_trivia"sv, StringView { option.help_string, strlen(option.help_string) });
|
object.set("display_trivia"sv, StringView { option.help_string, strlen(option.help_string) });
|
||||||
object.set("trailing_trivia"sv, option.argument_mode == OptionArgumentMode::Required ? " "sv : ""sv);
|
object.set("trailing_trivia"sv, option.argument_mode == OptionArgumentMode::Required ? " "sv : ""sv);
|
||||||
outln(file, "{}", object.serialized<StringBuilder>());
|
outln(file, "{}", object.serialized());
|
||||||
};
|
};
|
||||||
|
|
||||||
if (option_to_complete.starts_with("--"sv)) {
|
if (option_to_complete.starts_with("--"sv)) {
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
#include <AK/JsonObject.h>
|
#include <AK/JsonObject.h>
|
||||||
#include <AK/JsonValue.h>
|
#include <AK/JsonValue.h>
|
||||||
#include <AK/StringBuilder.h>
|
|
||||||
#include <LibCore/EventLoop.h>
|
#include <LibCore/EventLoop.h>
|
||||||
#include <LibDevTools/Connection.h>
|
#include <LibDevTools/Connection.h>
|
||||||
|
|
||||||
|
@ -34,7 +33,7 @@ Connection::~Connection() = default;
|
||||||
// https://firefox-source-docs.mozilla.org/devtools/backend/protocol.html#packets
|
// https://firefox-source-docs.mozilla.org/devtools/backend/protocol.html#packets
|
||||||
void Connection::send_message(JsonValue const& message)
|
void Connection::send_message(JsonValue const& message)
|
||||||
{
|
{
|
||||||
auto serialized = message.serialized<StringBuilder>();
|
auto serialized = message.serialized();
|
||||||
|
|
||||||
if constexpr (DEVTOOLS_DEBUG) {
|
if constexpr (DEVTOOLS_DEBUG) {
|
||||||
if (message.is_object() && message.as_object().get("error"sv).has_value())
|
if (message.is_object() && message.as_object().get("error"sv).has_value())
|
||||||
|
@ -43,7 +42,7 @@ void Connection::send_message(JsonValue const& message)
|
||||||
dbgln("\x1b[1;32m<<\x1b[0m {}", serialized);
|
dbgln("\x1b[1;32m<<\x1b[0m {}", serialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_socket->write_formatted("{}:{}", serialized.length(), serialized).is_error()) {
|
if (m_socket->write_formatted("{}:{}", serialized.byte_count(), serialized).is_error()) {
|
||||||
if (on_connection_closed)
|
if (on_connection_closed)
|
||||||
on_connection_closed();
|
on_connection_closed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ ErrorOr<void> encode(Encoder& encoder, ByteBuffer const& value)
|
||||||
template<>
|
template<>
|
||||||
ErrorOr<void> encode(Encoder& encoder, JsonValue const& value)
|
ErrorOr<void> encode(Encoder& encoder, JsonValue const& value)
|
||||||
{
|
{
|
||||||
return encoder.encode(value.serialized<StringBuilder>());
|
return encoder.encode(value.serialized());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
@ -274,7 +274,7 @@ inline void TestRunner::print_test_results_as_json() const
|
||||||
root.set("files_total"sv, m_counts.files_total);
|
root.set("files_total"sv, m_counts.files_total);
|
||||||
root.set("duration"sv, m_total_elapsed_time_in_ms / 1000.0);
|
root.set("duration"sv, m_total_elapsed_time_in_ms / 1000.0);
|
||||||
}
|
}
|
||||||
outln("{}", root.serialized<StringBuilder>());
|
outln("{}", root.serialized());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,7 +298,7 @@ ErrorOr<void, Client::WrappedError> Client::send_success_response(HTTP::HttpRequ
|
||||||
keep_alive = it->value.trim_whitespace().equals_ignoring_ascii_case("keep-alive"sv);
|
keep_alive = it->value.trim_whitespace().equals_ignoring_ascii_case("keep-alive"sv);
|
||||||
|
|
||||||
result = make_success_response(move(result));
|
result = make_success_response(move(result));
|
||||||
auto content = result.serialized<StringBuilder>();
|
auto content = result.serialized();
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
builder.append("HTTP/1.1 200 OK\r\n"sv);
|
builder.append("HTTP/1.1 200 OK\r\n"sv);
|
||||||
|
@ -309,7 +309,7 @@ ErrorOr<void, Client::WrappedError> Client::send_success_response(HTTP::HttpRequ
|
||||||
builder.append("Connection: keep-alive\r\n"sv);
|
builder.append("Connection: keep-alive\r\n"sv);
|
||||||
builder.append("Cache-Control: no-cache\r\n"sv);
|
builder.append("Cache-Control: no-cache\r\n"sv);
|
||||||
builder.append("Content-Type: application/json; charset=utf-8\r\n"sv);
|
builder.append("Content-Type: application/json; charset=utf-8\r\n"sv);
|
||||||
builder.appendff("Content-Length: {}\r\n", content.length());
|
builder.appendff("Content-Length: {}\r\n", content.byte_count());
|
||||||
builder.append("\r\n"sv);
|
builder.append("\r\n"sv);
|
||||||
builder.append(content);
|
builder.append(content);
|
||||||
|
|
||||||
|
@ -338,13 +338,13 @@ ErrorOr<void, Client::WrappedError> Client::send_error_response(HTTP::HttpReques
|
||||||
JsonObject result;
|
JsonObject result;
|
||||||
result.set("value"sv, move(error_response));
|
result.set("value"sv, move(error_response));
|
||||||
|
|
||||||
auto content = result.serialized<StringBuilder>();
|
auto content = result.serialized();
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
builder.appendff("HTTP/1.1 {} {}\r\n", error.http_status, reason);
|
builder.appendff("HTTP/1.1 {} {}\r\n", error.http_status, reason);
|
||||||
builder.append("Cache-Control: no-cache\r\n"sv);
|
builder.append("Cache-Control: no-cache\r\n"sv);
|
||||||
builder.append("Content-Type: application/json; charset=utf-8\r\n"sv);
|
builder.append("Content-Type: application/json; charset=utf-8\r\n"sv);
|
||||||
builder.appendff("Content-Length: {}\r\n", content.length());
|
builder.appendff("Content-Length: {}\r\n", content.byte_count());
|
||||||
builder.append("\r\n"sv);
|
builder.append("\r\n"sv);
|
||||||
builder.append(content);
|
builder.append(content);
|
||||||
|
|
||||||
|
|
|
@ -160,13 +160,13 @@ TEST_CASE(json_duplicate_keys)
|
||||||
json.set("test"sv, "foo"sv);
|
json.set("test"sv, "foo"sv);
|
||||||
json.set("test"sv, "bar"sv);
|
json.set("test"sv, "bar"sv);
|
||||||
json.set("test"sv, "baz"sv);
|
json.set("test"sv, "baz"sv);
|
||||||
EXPECT_EQ(json.serialized<StringBuilder>(), "{\"test\":\"baz\"}");
|
EXPECT_EQ(json.serialized(), "{\"test\":\"baz\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE(json_u64_roundtrip)
|
TEST_CASE(json_u64_roundtrip)
|
||||||
{
|
{
|
||||||
auto big_value = 0xffffffffffffffffull;
|
auto big_value = 0xffffffffffffffffull;
|
||||||
auto json = JsonValue(big_value).serialized<StringBuilder>();
|
auto json = JsonValue(big_value).serialized();
|
||||||
auto value = JsonValue::from_string(json);
|
auto value = JsonValue::from_string(json);
|
||||||
EXPECT_EQ_FORCE(value.is_error(), false);
|
EXPECT_EQ_FORCE(value.is_error(), false);
|
||||||
EXPECT_EQ(value.value().as_integer<u64>(), big_value);
|
EXPECT_EQ(value.value().as_integer<u64>(), big_value);
|
||||||
|
@ -531,7 +531,7 @@ TEST_CASE(json_array_serialized)
|
||||||
auto raw_json = R"(["Hello",2,3.14,4,"World"])"sv;
|
auto raw_json = R"(["Hello",2,3.14,4,"World"])"sv;
|
||||||
auto json_value = MUST(JsonValue::from_string(raw_json));
|
auto json_value = MUST(JsonValue::from_string(raw_json));
|
||||||
auto array = json_value.as_array();
|
auto array = json_value.as_array();
|
||||||
auto const& serialized_json = array.serialized<StringBuilder>();
|
auto const& serialized_json = array.serialized();
|
||||||
EXPECT_EQ(serialized_json, raw_json);
|
EXPECT_EQ(serialized_json, raw_json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -532,7 +532,7 @@ static bool g_in_assert = false;
|
||||||
assert_fail_result.set("assert_fail"sv, true);
|
assert_fail_result.set("assert_fail"sv, true);
|
||||||
assert_fail_result.set("result"sv, "assert_fail"sv);
|
assert_fail_result.set("result"sv, "assert_fail"sv);
|
||||||
assert_fail_result.set("output"sv, StringView { assert_failed_message, strlen(assert_failed_message) });
|
assert_fail_result.set("output"sv, StringView { assert_failed_message, strlen(assert_failed_message) });
|
||||||
outln(saved_stdout_fd, "RESULT {}{}", assert_fail_result.serialized<StringBuilder>(), '\0');
|
outln(saved_stdout_fd, "RESULT {}{}", assert_fail_result.serialized(), '\0');
|
||||||
// (Attempt to) Ensure that messages are written before quitting.
|
// (Attempt to) Ensure that messages are written before quitting.
|
||||||
fflush(saved_stdout_fd);
|
fflush(saved_stdout_fd);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
@ -733,7 +733,7 @@ int main(int argc, char** argv)
|
||||||
result_object.set("test"sv, path);
|
result_object.set("test"sv, path);
|
||||||
|
|
||||||
ScopeGuard output_guard = [&] {
|
ScopeGuard output_guard = [&] {
|
||||||
outln(saved_stdout_fd, "RESULT {}{}", result_object.serialized<StringBuilder>(), '\0');
|
outln(saved_stdout_fd, "RESULT {}{}", result_object.serialized(), '\0');
|
||||||
fflush(saved_stdout_fd);
|
fflush(saved_stdout_fd);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue