summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
Diffstat (limited to 'AK')
-rw-r--r--AK/Format.cpp5
-rw-r--r--AK/Format.h17
-rw-r--r--AK/Tests/TestFormat.cpp16
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)