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:
0diff --git a/src/init.cpp b/src/init.cpp
1index fb2028281a..c849f83b05 100644
2--- a/src/init.cpp
3+++ b/src/init.cpp
4@@ -1261,7 +1261,7 @@ static ChainstateLoadResult InitAndLoadChainstate(
5 return f();
6 } catch (const std::exception& e) {
7 LogError("%s\n", e.what());
8- return std::make_tuple(node::ChainstateLoadStatus::FAILURE, bilingual_str{_("Error opening block database")});
9+ return std::make_tuple(node::ChainstateLoadStatus::FAILURE, _("Error opening block database").str());
10 }
11 };
12 auto [status, error] = catch_exceptions([&] { return LoadChainstate(chainman, cache_sizes, options); });
13diff --git a/src/test/result_tests.cpp b/src/test/result_tests.cpp
14index 45337c6801..c829d56faa 100644
15--- a/src/test/result_tests.cpp
16+++ b/src/test/result_tests.cpp
17@@ -63,7 +63,7 @@ void ExpectSuccess(const util::Result<T>& result, const bilingual_str& str, Args
18 {
19 ExpectResult(result, true, str);
20 BOOST_CHECK_EQUAL(result.has_value(), true);
21- BOOST_CHECK_EQUAL(result.value(), T{std::forward<Args>(args)...});
22+ BOOST_CHECK_EQUAL(result.value(), T(std::forward<Args>(args)...));
23 BOOST_CHECK_EQUAL(&result.value(), &*result);
24 }
25
26@@ -89,8 +89,8 @@ BOOST_AUTO_TEST_CASE(check_value_or)
27 BOOST_CHECK_EQUAL(IntFn(10, false).value_or(20), 20);
28 BOOST_CHECK_EQUAL(NoCopyFn(10, true).value_or(20), 10);
29 BOOST_CHECK_EQUAL(NoCopyFn(10, false).value_or(20), 20);
30- BOOST_CHECK_EQUAL(StrFn(Untranslated("A"), true).value_or(Untranslated("B")), bilingual_str{Untranslated("A")});
31- BOOST_CHECK_EQUAL(StrFn(Untranslated("A"), false).value_or(Untranslated("B")), bilingual_str{Untranslated("B")});
32+ BOOST_CHECK_EQUAL(StrFn(Untranslated("A"), true).value_or(Untranslated("B")), Untranslated("A").str());
33+ BOOST_CHECK_EQUAL(StrFn(Untranslated("A"), false).value_or(Untranslated("B")), Untranslated("B").str());
34 }
35
36 BOOST_AUTO_TEST_SUITE_END()
37diff --git a/src/util/translation.h b/src/util/translation.h
38index 08df892733..a06f7b982f 100644
39--- a/src/util/translation.h
40+++ b/src/util/translation.h
41@@ -14,24 +14,6 @@
42 /** Translate a message to the native language of the user. */
43 const extern std::function<std::string(const char*)> G_TRANSLATION_FUN;
44
45-namespace util {
46-/**
47- * Translation function.
48- * If no translation function is set, simply return the input.
49- */
50-inline std::string translate(const char* lit)
51-{
52- return G_TRANSLATION_FUN ? G_TRANSLATION_FUN(lit) : lit;
53-}
54-/** Type to denote whether an orginal string literal is translatable */
55-template <bool translatable = true>
56-struct Original {
57- const char* const lit;
58- consteval Original(const char* str) : lit{str} { assert(lit); }
59- std::string translate() const { return translatable ? util::translate(lit) : lit; }
60-};
61-} // namespace util
62-
63 /**
64 * Bilingual messages:
65 * - in GUI: user's native language + untranslated (i.e. English)
66@@ -41,13 +23,6 @@ struct bilingual_str {
67 std::string original;
68 std::string translated;
69
70- bilingual_str() = default;
71- bilingual_str(std::string original, std::string translated) : original{original}, translated{translated} {}
72- template <bool translatable>
73- bilingual_str(util::Original<translatable> original) : original{original.lit}, translated{original.translate()}
74- {
75- }
76-
77 bilingual_str& operator+=(const bilingual_str& rhs)
78 {
79 original += rhs.original;
80@@ -73,6 +48,26 @@ inline bilingual_str operator+(bilingual_str lhs, const bilingual_str& rhs)
81 return lhs;
82 }
83
84+namespace util {
85+/**
86+ * Translation function.
87+ * If no translation function is set, simply return the input.
88+ */
89+inline std::string translate(const char* lit)
90+{
91+ return G_TRANSLATION_FUN ? G_TRANSLATION_FUN(lit) : lit;
92+}
93+/** Type to denote whether an orginal string literal is translatable */
94+template <bool translatable = true>
95+struct Original {
96+ const char* const lit;
97+ consteval Original(const char* str) : lit{str} { assert(lit); }
98+ std::string translate() const { return translatable ? util::translate(lit) : lit; }
99+ bilingual_str str() const { return {lit, translate()}; }
100+ operator bilingual_str() const { return str(); }
101+};
102+} // namespace util
103+
104 consteval auto _(util::Original<true> str) { return str; }
105
106 /** Mark a bilingual_str as untranslated */