|
|
|
#include "l10n.hpp"
|
|
|
|
|
|
|
|
#include <components/debug/debuglog.hpp>
|
|
|
|
#include <components/l10n/manager.hpp>
|
|
|
|
#include <components/lua/luastate.hpp>
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
struct L10nContext
|
|
|
|
{
|
|
|
|
std::shared_ptr<const l10n::MessageBundles> mData;
|
|
|
|
};
|
|
|
|
|
|
|
|
void getICUArgs(std::string_view messageId, const sol::table& table, std::vector<icu::UnicodeString>& argNames,
|
|
|
|
std::vector<icu::Formattable>& args)
|
|
|
|
{
|
|
|
|
for (auto& [key, value] : table)
|
|
|
|
{
|
|
|
|
// Argument values
|
|
|
|
if (value.is<std::string>())
|
|
|
|
args.push_back(icu::Formattable(LuaUtil::cast<std::string>(value).c_str()));
|
|
|
|
// Note: While we pass all numbers as doubles, they still seem to be handled appropriately.
|
|
|
|
// Numbers can be forced to be integers using the argType number and argStyle integer
|
|
|
|
// E.g. {var, number, integer}
|
|
|
|
else if (value.is<double>())
|
|
|
|
args.push_back(icu::Formattable(LuaUtil::cast<double>(value)));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Log(Debug::Error) << "Unrecognized argument type for key \"" << LuaUtil::cast<std::string>(key)
|
|
|
|
<< "\" when formatting message \"" << messageId << "\"";
|
|
|
|
}
|
|
|
|
|
|
|
|
// Argument names
|
|
|
|
const auto str = LuaUtil::cast<std::string>(key);
|
|
|
|
argNames.push_back(icu::UnicodeString::fromUTF8(icu::StringPiece(str.data(), str.size())));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace sol
|
|
|
|
{
|
|
|
|
template <>
|
|
|
|
struct is_automagical<L10nContext> : std::false_type
|
|
|
|
{
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace LuaUtil
|
|
|
|
{
|
|
|
|
sol::function initL10nLoader(lua_State* L, l10n::Manager* manager)
|
|
|
|
{
|
|
|
|
sol::state_view lua(L);
|
|
|
|
sol::usertype<L10nContext> ctxDef = lua.new_usertype<L10nContext>("L10nContext");
|
|
|
|
ctxDef[sol::meta_function::call]
|
|
|
|
= [](const L10nContext& ctx, std::string_view key, sol::optional<sol::table> args) {
|
|
|
|
std::vector<icu::Formattable> argValues;
|
|
|
|
std::vector<icu::UnicodeString> argNames;
|
|
|
|
if (args)
|
|
|
|
getICUArgs(key, *args, argNames, argValues);
|
|
|
|
return ctx.mData->formatMessage(key, argNames, argValues);
|
|
|
|
};
|
|
|
|
|
|
|
|
return sol::make_object(
|
|
|
|
lua, [manager](const std::string& contextName, sol::optional<std::string> fallbackLocale) {
|
|
|
|
if (fallbackLocale)
|
|
|
|
return L10nContext{ manager->getContext(contextName, *fallbackLocale) };
|
|
|
|
else
|
|
|
|
return L10nContext{ manager->getContext(contextName) };
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|