Also (not sure about this, but) it might be nice to add an explicit conversion method to Original class, so we could write something like _("Error opening block database").str() instead of bilingual_str{_("Error opening block database")}
Sure, I am happy to add bilingual_str str() and operator bilingual_str() to the Original type and remove the constructors from bilingual_str. However, this means that calling bilingual_str{Original{}} is now forbidden and one would have to use () over {}, or call the .str() method.
Let me know if this is fine and I should go ahead and push this diff:
diff --git a/src/init.cpp b/src/init.cpp
index fb2028281a..c849f83b05 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -1261,7 +1261,7 @@ static ChainstateLoadResult InitAndLoadChainstate(
return f();
} catch (const std::exception& e) {
LogError("%s\n", e.what());
- return std::make_tuple(node::ChainstateLoadStatus::FAILURE, bilingual_str{_("Error opening block database")});
+ return std::make_tuple(node::ChainstateLoadStatus::FAILURE, _("Error opening block database").str());
}
};
auto [status, error] = catch_exceptions([&] { return LoadChainstate(chainman, cache_sizes, options); });
diff --git a/src/test/result_tests.cpp b/src/test/result_tests.cpp
index 45337c6801..c829d56faa 100644
--- a/src/test/result_tests.cpp
+++ b/src/test/result_tests.cpp
@@ -63,7 +63,7 @@ void ExpectSuccess(const util::Result<T>& result, const bilingual_str& str, Args
{
ExpectResult(result, true, str);
BOOST_CHECK_EQUAL(result.has_value(), true);
- BOOST_CHECK_EQUAL(result.value(), T{std::forward<Args>(args)...});
+ BOOST_CHECK_EQUAL(result.value(), T(std::forward<Args>(args)...));
BOOST_CHECK_EQUAL(&result.value(), &*result);
}
@@ -89,8 +89,8 @@ BOOST_AUTO_TEST_CASE(check_value_or)
BOOST_CHECK_EQUAL(IntFn(10, false).value_or(20), 20);
BOOST_CHECK_EQUAL(NoCopyFn(10, true).value_or(20), 10);
BOOST_CHECK_EQUAL(NoCopyFn(10, false).value_or(20), 20);
- BOOST_CHECK_EQUAL(StrFn(Untranslated("A"), true).value_or(Untranslated("B")), bilingual_str{Untranslated("A")});
- BOOST_CHECK_EQUAL(StrFn(Untranslated("A"), false).value_or(Untranslated("B")), bilingual_str{Untranslated("B")});
+ BOOST_CHECK_EQUAL(StrFn(Untranslated("A"), true).value_or(Untranslated("B")), Untranslated("A").str());
+ BOOST_CHECK_EQUAL(StrFn(Untranslated("A"), false).value_or(Untranslated("B")), Untranslated("B").str());
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/util/translation.h b/src/util/translation.h
index 08df892733..a06f7b982f 100644
--- a/src/util/translation.h
+++ b/src/util/translation.h
@@ -14,24 +14,6 @@
/** Translate a message to the native language of the user. */
const extern std::function<std::string(const char*)> G_TRANSLATION_FUN;
-namespace util {
-/**
- * Translation function.
- * If no translation function is set, simply return the input.
- */
-inline std::string translate(const char* lit)
-{
- return G_TRANSLATION_FUN ? G_TRANSLATION_FUN(lit) : lit;
-}
-/** Type to denote whether an orginal string literal is translatable */
-template <bool translatable = true>
-struct Original {
- const char* const lit;
- consteval Original(const char* str) : lit{str} { assert(lit); }
- std::string translate() const { return translatable ? util::translate(lit) : lit; }
-};
-} // namespace util
-
/**
* Bilingual messages:
* - in GUI: user's native language + untranslated (i.e. English)
@@ -41,13 +23,6 @@ struct bilingual_str {
std::string original;
std::string translated;
- bilingual_str() = default;
- bilingual_str(std::string original, std::string translated) : original{original}, translated{translated} {}
- template <bool translatable>
- bilingual_str(util::Original<translatable> original) : original{original.lit}, translated{original.translate()}
- {
- }
-
bilingual_str& operator+=(const bilingual_str& rhs)
{
original += rhs.original;
@@ -73,6 +48,26 @@ inline bilingual_str operator+(bilingual_str lhs, const bilingual_str& rhs)
return lhs;
}
+namespace util {
+/**
+ * Translation function.
+ * If no translation function is set, simply return the input.
+ */
+inline std::string translate(const char* lit)
+{
+ return G_TRANSLATION_FUN ? G_TRANSLATION_FUN(lit) : lit;
+}
+/** Type to denote whether an orginal string literal is translatable */
+template <bool translatable = true>
+struct Original {
+ const char* const lit;
+ consteval Original(const char* str) : lit{str} { assert(lit); }
+ std::string translate() const { return translatable ? util::translate(lit) : lit; }
+ bilingual_str str() const { return {lit, translate()}; }
+ operator bilingual_str() const { return str(); }
+};
+} // namespace util
+
consteval auto _(util::Original<true> str) { return str; }
/** Mark a bilingual_str as untranslated */