mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-11 05:25:32 +03:00
AK+Format: Support all format specifiers for strings.
The following is now possible: outf("{:.4}", "abcdef"); // abcd outf("{:*<8}", "abcdef"); // abcdef**
This commit is contained in:
parent
c0d9daadb0
commit
71b7ef0992
Notes:
sideshowbarker
2024-07-19 02:08:08 +09:00
Author: https://github.com/asynts Commit: https://github.com/SerenityOS/serenity/commit/71b7ef0992b Pull-request: https://github.com/SerenityOS/serenity/pull/3640
@ -300,24 +300,65 @@ void StandardFormatter::parse(FormatterContext& context)
|
||||
ASSERT(parser.is_eof());
|
||||
}
|
||||
|
||||
void Formatter<StringView>::format(StringBuilder& builder, StringView value, FormatterContext&)
|
||||
void Formatter<StringView>::format(StringBuilder& builder, StringView value, FormatterContext& context)
|
||||
{
|
||||
if (m_align != Align::Default)
|
||||
TODO();
|
||||
if (m_sign != Sign::Default)
|
||||
ASSERT_NOT_REACHED();
|
||||
if (m_alternative_form)
|
||||
ASSERT_NOT_REACHED();
|
||||
if (m_zero_pad)
|
||||
ASSERT_NOT_REACHED();
|
||||
if (m_width != value_not_set)
|
||||
TODO();
|
||||
if (m_precision != value_not_set)
|
||||
TODO();
|
||||
if (m_mode != Mode::Default && m_mode != Mode::String)
|
||||
ASSERT_NOT_REACHED();
|
||||
if (m_width != value_not_set && m_precision != value_not_set)
|
||||
ASSERT_NOT_REACHED();
|
||||
|
||||
builder.append(value);
|
||||
if (m_align == Align::Default)
|
||||
m_align = Align::Left;
|
||||
|
||||
const auto width = decode_value(m_width, context);
|
||||
const auto precision = decode_value(m_precision, context);
|
||||
|
||||
const auto put_padding = [&](size_t amount, char fill) {
|
||||
for (size_t i = 0; i < amount; ++i)
|
||||
builder.append(fill);
|
||||
};
|
||||
const auto put_bytes = [&](ReadonlyBytes bytes) {
|
||||
for (size_t i = 0; i < bytes.size(); ++i)
|
||||
builder.append(static_cast<char>(bytes[i]));
|
||||
};
|
||||
|
||||
auto used_by_string = value.length();
|
||||
if (precision != value_not_set)
|
||||
used_by_string = min(used_by_string, precision);
|
||||
|
||||
const auto used_by_padding = width < used_by_string ? 0 : width - used_by_string;
|
||||
|
||||
if (m_align == Align::Left) {
|
||||
const auto used_by_right_padding = used_by_padding;
|
||||
|
||||
put_bytes(value.bytes().trim(used_by_string));
|
||||
put_padding(used_by_right_padding, m_fill);
|
||||
return;
|
||||
}
|
||||
if (m_align == Align::Center) {
|
||||
const auto used_by_left_padding = used_by_padding / 2;
|
||||
const auto used_by_right_padding = ceil_div<size_t, size_t>(used_by_padding, 2);
|
||||
|
||||
put_padding(used_by_left_padding, m_fill);
|
||||
put_bytes(value.bytes().trim(used_by_string));
|
||||
put_padding(used_by_right_padding, m_fill);
|
||||
return;
|
||||
}
|
||||
if (m_align == Align::Right) {
|
||||
const auto used_by_left_padding = used_by_padding;
|
||||
|
||||
put_padding(used_by_left_padding, m_fill);
|
||||
put_bytes(value.bytes().trim(used_by_string));
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -141,7 +141,7 @@ inline size_t convert_unsigned_to_string(
|
||||
};
|
||||
|
||||
const auto used_by_field = used_by_significant_digits + used_by_prefix;
|
||||
const auto used_by_padding = static_cast<size_t>(max<ssize_t>(0, static_cast<ssize_t>(width) - static_cast<ssize_t>(used_by_field)));
|
||||
const auto used_by_padding = width < used_by_field ? 0 : width - used_by_field;
|
||||
|
||||
if (align == Align::Left) {
|
||||
const auto used_by_right_padding = used_by_padding;
|
||||
|
@ -122,4 +122,12 @@ TEST_CASE(replacement_field)
|
||||
EXPECT_EQ(String::formatted("{:0{}}", 1, 3), "001");
|
||||
}
|
||||
|
||||
TEST_CASE(complex_string_specifiers)
|
||||
{
|
||||
EXPECT_EQ(String::formatted("{:.8}", "123456789"), "12345678");
|
||||
EXPECT_EQ(String::formatted("{:9}", "abcd"), "abcd ");
|
||||
EXPECT_EQ(String::formatted("{:>9}", "abcd"), " abcd");
|
||||
EXPECT_EQ(String::formatted("{:^9}", "abcd"), " abcd ");
|
||||
}
|
||||
|
||||
TEST_MAIN(Format)
|
||||
|
Loading…
Reference in New Issue
Block a user