IceShard 1
A personal game engine project, with development focused on 2D/2.5D games.
Loading...
Searching...
No Matches
i18n_detail.hxx
Go to the documentation of this file.
1#pragma once
2#include <ice/string.hxx>
3#include <fmt/format.h>
4
5namespace ice::i18n
6{
7
8 struct I18NFlags
9 {
10 constexpr explicit I18NFlags(ice::String data) noexcept
11 : _data{ data }
12 {
13 if (_data.not_empty() && _data.back() == '|')
14 {
15 _data = _data.substr(0, _data.size() - 1);
16 }
17 }
18
19 constexpr bool operator==(ice::String rhs) const noexcept { return _data == rhs; }
20
21 constexpr auto language(fmt::format_args const& args) const noexcept -> ice::String;
22
24 };
25
26 namespace detail
27 {
28
29 template<typename ArgType>
31 {
32 ArgType& _reference;
33
34 constexpr bool operator()(ArgType arg) const noexcept
35 {
36 _reference = arg;
37 return true;
38 }
39
40 constexpr bool operator()(auto const& unused) const noexcept
41 {
42 return false;
43 }
44 };
45
46 } // namespace detail
47
48 constexpr auto I18NFlags::language(fmt::format_args const& args) const noexcept -> ice::String
49 {
50 ice::nindex const lang_start = _data.find_first_of('@');
51 ice::nindex const lang_end = _data.find_first_of(", |", lang_start);
52 if (lang_start == ice::nindex_none)
53 {
54 return { };
55 }
56
57 ice::String const lang = _data.substr(lang_start + 1, lang_end - lang_start - 1);
58 if (lang[0] == '{')
59 {
60 ice::nindex const lang_arg_end = lang.find_first_of('}');
61 if (lang_arg_end != std::string_view::npos && lang_arg_end > 1)
62 {
63 ice::i32 const id = atol(lang.data());
64 // if (ice::from_chars(lang, id) == S_Ok)
65 {
66 ice::String result{};
67 {
68 // Find the format arg result
70 args.get(id).visit(lang_arg_visitor);
71 }
73 return result;
74 }
75 }
76 }
77
78 return lang;
79 }
80
81 constexpr void parse(
82 ice::String in_str,
83 ice::u32& out_hash,
84 ice::u8& out_path,
85 ice::u8& out_key,
86 ice::u8& out_flags,
87 ice::u8& out_fallback
88 ) noexcept
89 {
90 ice::nindex const path_sep = in_str.find_first_of('/');
92 out_path = (path_sep + 1).u8();
93
94 ice::String str = in_str.substr(path_sep + 1);
95 ice::nindex const key_sep = str.find_first_of(" |");
96 ice::String const key = str.substr(0, key_sep);
97 out_key = key.size().u8();
98
99 // Create a hash from the reference value. `a.path/a.key`
100 out_hash = ice::hash32(in_str.substr(key_sep + 1));
101
102 // Find additional params or the fallback string
103 if (key_sep.is_valid())
104 {
105 str = str.substr(key_sep);
106 if (str[0] == ' ')
107 {
108 ice::nindex const flags_sep = str.find_first_of('|');
109 ICE_ASSERT_CORE(flags_sep.value_or(2) >= 2); // We need at least one more character for flags to be valid!
110
111 if (flags_sep.is_valid())
112 {
113 out_flags = flags_sep.u8() - 1u;
114 out_fallback = (str.size() - flags_sep).u8() - 1u;
115 }
116 else
117 {
118 out_flags = str.size().u8() - 1u;
119 }
120 }
121 else
122 {
123 out_flags = 0;
124 out_fallback = str.size().u8() - 1u;
125 }
126 }
127 }
128
129} // namespace ice::i18n
#define ICE_ASSERT_CORE(expression)
Definition assert_core.hxx:43
Definition span.hxx:129
Definition i18n_detail.hxx:27
Definition i18n_detail.hxx:6
constexpr void parse(ice::String in_str, ice::u32 &out_hash, ice::u8 &out_path, ice::u8 &out_key, ice::u8 &out_flags, ice::u8 &out_fallback) noexcept
Definition i18n_detail.hxx:81
constexpr auto strptr_size(CharType const *str) noexcept -> ice::ncount::base_type
Definition string_concepts.hxx:72
ice::BasicString< char > String
Definition string.hxx:82
std::int32_t i32
Definition types.hxx:21
constexpr auto hash32(ice::String value) noexcept -> ice::u32
Definition string.hxx:105
std::uint32_t u32
Definition types.hxx:26
std::uint8_t u8
Definition types.hxx:24
static constexpr ice::nindex_invalid_t nindex_none
Definition nindex.hxx:56
constexpr auto size() const noexcept -> SizeType
Definition string.hxx:57
SizeType::base_type _count
Definition string.hxx:26
constexpr auto data() const noexcept -> ValueType *
Definition string.hxx:56
ValueType * _data
Definition string.hxx:25
ice::String _data
Definition i18n_detail.hxx:23
constexpr I18NFlags(ice::String data) noexcept
Definition i18n_detail.hxx:10
constexpr auto language(fmt::format_args const &args) const noexcept -> ice::String
Definition i18n_detail.hxx:48
constexpr bool operator==(ice::String rhs) const noexcept
Definition i18n_detail.hxx:19
Definition i18n_detail.hxx:31
constexpr bool operator()(auto const &unused) const noexcept
Definition i18n_detail.hxx:40
constexpr bool operator()(ArgType arg) const noexcept
Definition i18n_detail.hxx:34
ArgType & _reference
Definition i18n_detail.hxx:32
Definition nindex.hxx:13
constexpr auto u8() const noexcept
Definition nvalue.hxx:111
constexpr bool is_valid(this Self self) noexcept
Definition nvalue.hxx:86
constexpr auto value_or(this Self self, ice::concepts::NValueCompatibleType auto fallback) noexcept
Definition nvalue.hxx:89
constexpr bool not_empty(this Self const &self) noexcept
Definition readonly_operations.hxx:22
constexpr auto find_first_of(this Self const &self, typename Self::CharType character_value, ice::nindex start=0) noexcept -> ice::nindex
Definition readonly_operations.hxx:75
constexpr auto back(this Self const &self) noexcept -> typename Self::CharType
Definition readonly_operations.hxx:34
constexpr auto substr(this Self const &self, ice::nindex pos, ice::ncount len={}) noexcept -> typename Self::StringType
Definition readonly_operations.hxx:40