morph
0.1.0
Asynchronous bridge between GUI thread and business models
Toggle main menu visibility
Loading...
Searching...
No Matches
i18n.hpp
Go to the documentation of this file.
1
// SPDX-License-Identifier: Apache-2.0
2
3
#pragma once
4
5
/// @file render/i18n.hpp
6
/// @brief The renderer-side translation-catalog seam over morph's derived
7
/// message keys (`morph::forms::i18n`, `forms/i18n.hpp`).
8
///
9
/// `morph::render` is client-side only and never appears on the wire — it is
10
/// the C++ side of the client-side rendering seam. morph ships this seam and the resolution algorithm below; it
11
/// defines **no** translation storage format. A host adapts whatever catalog it already owns (Qt `QTranslator`/`.qm`,
12
/// a JSON bundle, a database) into the one `TranslationProvider` signature.
13
14
#include <functional>
15
#include <optional>
16
#include <string>
17
#include <string_view>
18
19
namespace
morph::render {
20
21
/// @brief A host-supplied catalog lookup: `key`/`bcp47Locale` -> translated
22
/// text, or `std::nullopt` on a miss.
23
///
24
/// A default-constructed (empty) `TranslationProvider` means "no catalog
25
/// installed" — `resolveText` treats it the same as a provider that misses
26
/// on every key.
27
using
TranslationProvider
=
28
std::function<std::optional<std::string>(std::string_view key, std::string_view bcp47Locale)>;
29
30
/// @brief Resolves one display slot's text: explicit key, then derived key,
31
/// then the schema literal.
32
///
33
/// Tried in order, most specific first:
34
/// 1. @p explicitKey (a host-declared `x-i18nKey`-derived key), if present;
35
/// 2. @p derivedKey (`morph::forms::i18n::fieldKey` or one of its siblings);
36
/// 3. a miss at both falls back to @p schemaLiteral — the schema's
37
/// authored `title` / `description` / `x-placeholder` / group or step
38
/// title, unchanged.
39
/// An empty/unset @p provider ("no catalog installed") skips straight to
40
/// @p schemaLiteral, matching an unconfigured renderer's behavior exactly.
41
/// @param provider The host's catalog lookup.
42
/// @param bcp47Locale The locale to resolve against (e.g. `"fr-FR"`).
43
/// @param explicitKey The field/group/rule/step's declared `x-i18nKey`-based
44
/// key, or `std::nullopt` when none is declared.
45
/// @param derivedKey The mechanically-derived key for this slot.
46
/// @param schemaLiteral The schema's authored fallback text for this slot.
47
/// @return The resolved display text.
48
// NOLINTBEGIN(bugprone-easily-swappable-parameters)
49
// `derivedKey` and `schemaLiteral` are adjacent `std::string_view`s, and the
50
// check is right that swapping them would be silent and wrong: the derived key
51
// would be rendered to the user as display text, and the schema's authored
52
// title would be looked up in the catalog, miss, and fall back to the key. No
53
// type or arity error would catch it.
54
//
55
// They stay in this order because the order *is* the contract. The three
56
// parameters are the resolution chain in precedence order -- explicit key, then
57
// derived key, then the schema literal as the fallback -- which is how the
58
// @brief above states it, how the body below tries them, and how
59
// docs/spec/forms/forms.md specifies it.
60
//
61
// Strong types would remove the hazard outright, but a `TranslationKey` wrapper
62
// on this seam would have to be threaded through every caller in morph::forms,
63
// which is a design change to the renderer boundary and not a lint fix. If that
64
// is ever done, delete this suppression rather than widening it.
65
[[nodiscard]]
inline
std::string
resolveText
(
const
TranslationProvider
& provider, std::string_view bcp47Locale,
66
const
std::optional<std::string>& explicitKey,
67
std::string_view derivedKey, std::string_view schemaLiteral) {
68
// NOLINTEND(bugprone-easily-swappable-parameters)
69
if
(provider) {
70
if
(explicitKey.has_value()) {
71
if
(
auto
hit = provider(*explicitKey, bcp47Locale)) {
72
return
*hit;
73
}
74
}
75
if
(
auto
hit = provider(derivedKey, bcp47Locale)) {
76
return
*hit;
77
}
78
}
79
return
std::string{schemaLiteral};
80
}
81
82
}
// namespace morph::render
morph::render::TranslationProvider
std::function< std::optional< std::string >(std::string_view key, std::string_view bcp47Locale)> TranslationProvider
A host-supplied catalog lookup: key/bcp47Locale -> translated text, or std::nullopt on a miss.
Definition
i18n.hpp:27
morph::render::resolveText
std::string resolveText(const TranslationProvider &provider, std::string_view bcp47Locale, const std::optional< std::string > &explicitKey, std::string_view derivedKey, std::string_view schemaLiteral)
Resolves one display slot's text: explicit key, then derived key, then the schema literal.
Definition
i18n.hpp:65
morph
render
i18n.hpp
Generated by
1.17.0