diff --git a/docs/metadata/data_structures/message.rst b/docs/metadata/data_structures/message.rst index c0600caa..1d74ee3a 100644 --- a/docs/metadata/data_structures/message.rst +++ b/docs/metadata/data_structures/message.rst @@ -37,7 +37,7 @@ Messages are given as key-value maps. ``string list`` - A list of CommonMark strings to be substituted into the message content string. The content string must use numbered specifiers (``%1%``, ``%2%``, etc.), where the numbers correspond to the position of the substitution string in this list to use, to denote where these strings are to be substituted. + A list of CommonMark strings to be substituted into the message content string. The content string must use numbered specifiers (``{0}``, ``{1}``, etc.), where the numbers correspond to the position of the substitution string in this list to use, to denote where these strings are to be substituted. .. _languages: @@ -102,7 +102,7 @@ In English, .. code-block:: yaml type: say - content: 'A newer version of %1% [is available](%2%).' + content: 'A newer version of {0} [is available]({1}).' subs: - 'this plugin' - 'http://www.example.com' diff --git a/src/api/helpers/crc.cpp b/src/api/helpers/crc.cpp index 927a79a5..307b2d05 100644 --- a/src/api/helpers/crc.cpp +++ b/src/api/helpers/crc.cpp @@ -24,8 +24,9 @@ #include "api/helpers/crc.h" +#include + #include -#include #include #include "api/helpers/logging.h" @@ -80,7 +81,5 @@ uint32_t GetCrc32(const std::filesystem::path& filename) { } } -std::string CrcToString(uint32_t crc) { - return (boost::format("%08X") % crc).str(); -} +std::string CrcToString(uint32_t crc) { return fmt::format("{:08X}", crc); } } diff --git a/src/api/metadata/yaml/message.h b/src/api/metadata/yaml/message.h index b13238f1..effb1f3e 100644 --- a/src/api/metadata/yaml/message.h +++ b/src/api/metadata/yaml/message.h @@ -26,9 +26,10 @@ #define YAML_CPP_SUPPORT_MERGE_KEYS +#include +#include #include -#include #include #include @@ -103,16 +104,17 @@ struct convert { if (node["subs"]) { std::vector subs = node["subs"].as>(); + + fmt::dynamic_format_arg_store formatArgStore; + for (const auto& sub : subs) { + formatArgStore.push_back(sub); + } + for (auto& mc : content) { - boost::format f(mc.GetText()); - - for (const auto& sub : subs) { - f = f % sub; - } - try { - mc = loot::MessageContent(f.str(), mc.GetLanguage()); - } catch (const boost::io::format_error& e) { + const auto text = fmt::vformat(mc.GetText(), formatArgStore); + mc = loot::MessageContent(text, mc.GetLanguage()); + } catch (const fmt::format_error& e) { throw RepresentationException( node.Mark(), std::string("bad conversion: content substitution error: ") + diff --git a/src/tests/api/internals/metadata/message_test.h b/src/tests/api/internals/metadata/message_test.h index 226465de..0a6e4d8d 100644 --- a/src/tests/api/internals/metadata/message_test.h +++ b/src/tests/api/internals/metadata/message_test.h @@ -615,7 +615,7 @@ TEST_P( decodingFromYamlShouldApplySubstitutionsWhenThereIsOnlyOneContentString) { YAML::Node node = YAML::Load( "type: say\n" - "content: con%1%tent1\n" + "content: con{0}tent1\n" "subs:\n" " - sub1"); Message message = node.as(); @@ -630,9 +630,9 @@ TEST_P(MessageTest, "type: say\n" "content:\n" " - lang: en\n" - " text: content1 %1%\n" + " text: content1 {0}\n" " - lang: fr\n" - " text: content2 %1%\n" + " text: content2 {0}\n" "subs:\n" " - sub"); Message message = node.as(); @@ -649,7 +649,7 @@ TEST_P( decodingFromYamlShouldThrowIfTheContentStringExpectsMoreSubstitutionsThanExist) { YAML::Node node = YAML::Load( "type: say\n" - "content: '%1% %2%'\n" + "content: '{0} {1}'\n" "subs:\n" " - sub1"); @@ -662,10 +662,10 @@ TEST_P(MessageTest, decodingFromYamlShouldIgnoreSubstitutionSyntaxIfNoSubstitutionsExist) { YAML::Node node = YAML::Load( "type: say\n" - "content: con%1%tent1\n"); + "content: con{0}tent1\n"); Message message = node.as(); - EXPECT_EQ(MessageContents({MessageContent("con%1%tent1")}), + EXPECT_EQ(MessageContents({MessageContent("con{0}tent1")}), message.GetContent()); }