diff options
author | asynts <asynts@gmail.com> | 2021-01-09 01:00:22 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-01-09 21:11:09 +0100 |
commit | 1160817a9e3b0084ab2be469a21626354a1b0afd (patch) | |
tree | 50acf8335a01b25654220a8c9d8a1660919a3844 /AK | |
parent | 9a842ec4192ea0cdd4d4e6b6ca45aff09195c64c (diff) | |
download | serenity-1160817a9e3b0084ab2be469a21626354a1b0afd.zip |
AK: Add Formatter<FormatString> as helper class.
Diffstat (limited to 'AK')
-rw-r--r-- | AK/Format.cpp | 5 | ||||
-rw-r--r-- | AK/Format.h | 17 | ||||
-rw-r--r-- | AK/Tests/TestFormat.cpp | 16 |
3 files changed, 37 insertions, 1 deletions
diff --git a/AK/Format.cpp b/AK/Format.cpp index 14ed0459dd..0132807ed4 100644 --- a/AK/Format.cpp +++ b/AK/Format.cpp @@ -521,6 +521,11 @@ void Formatter<StringView>::format(FormatBuilder& builder, StringView value) builder.put_string(value, m_align, m_width.value(), m_precision.value(), m_fill); } +void Formatter<FormatString>::vformat(FormatBuilder& builder, StringView fmtstr, TypeErasedFormatParams params) +{ + return Formatter<String>::format(builder, String::vformatted(fmtstr, params)); +} + template<typename T> void Formatter<T, typename EnableIf<IsIntegral<T>::value>::Type>::format(FormatBuilder& builder, T value) { diff --git a/AK/Format.h b/AK/Format.h index 90030765ec..63b1d3fab2 100644 --- a/AK/Format.h +++ b/AK/Format.h @@ -359,7 +359,7 @@ struct Formatter<std::nullptr_t> : Formatter<FlatPtr> { } }; -void vformat(StringBuilder& builder, StringView fmtstr, TypeErasedFormatParams); +void vformat(StringBuilder&, StringView fmtstr, TypeErasedFormatParams); void vformat(const LogStream& stream, StringView fmtstr, TypeErasedFormatParams); #ifndef KERNEL @@ -435,6 +435,20 @@ template<typename T> struct Formatter<FormatIfSupported<T>> : __FormatIfSupported<T, HasFormatter<T>::value> { }; +// This is a helper class, the idea is that if you want to implement a formatter you can inherit +// from this class to "break down" the formatting. +struct FormatString { +}; +template<> +struct Formatter<FormatString> : Formatter<String> { + template<typename... Parameters> + void format(FormatBuilder& builder, StringView fmtstr, const Parameters&... parameters) + { + vformat(builder, fmtstr, VariadicFormatParams { parameters... }); + } + void vformat(FormatBuilder& builder, StringView fmtstr, TypeErasedFormatParams params); +}; + } // namespace AK #ifndef KERNEL @@ -448,3 +462,4 @@ using AK::warnln; using AK::dbgln; using AK::FormatIfSupported; +using AK::FormatString; diff --git a/AK/Tests/TestFormat.cpp b/AK/Tests/TestFormat.cpp index cfe7fe2950..609582b6ae 100644 --- a/AK/Tests/TestFormat.cpp +++ b/AK/Tests/TestFormat.cpp @@ -274,4 +274,20 @@ TEST_CASE(format_nullptr) EXPECT_EQ(String::formatted("{}", nullptr), String::formatted("{:p}", static_cast<FlatPtr>(0))); } +struct C { + int i; +}; +template<> +struct AK::Formatter<C> : AK::Formatter<FormatString> { + void format(FormatBuilder& builder, C c) + { + return AK::Formatter<FormatString>::format(builder, "C(i={})", c.i); + } +}; + +TEST_CASE(use_format_string_formatter) +{ + EXPECT_EQ(String::formatted("{:*<10}", C { 42 }), "C(i=42)***"); +} + TEST_MAIN(Format) |