blob: 4de9c105521d5b4f6cee1acad698b1d9240a3595 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Provides an API for looking up localized message strings.
// Localized message strings are strings which have a different value based on
// the locale that is supplied as the context of the lookup. So, if your locale
// is, say "en", your `lookup.string(42)` may return `Hello world`, but if your
// locale is "nl", your `lookup.string(42)` may return `Groetjes, wereld`.
// Example use:
// ```
// std::vector<std::string> locale_ids = {"nl-NL"};
// auto result = Lookup::New(locale_ids);
// if (result.is_error()) {
// // handle error
// return;
// }
// auto lookup = result.value();
// auto lookup_result = lookup.string(42);
// if (lookup_result.is_error()) {
// // handle error
// return;
// }
// std::string_view message = lookup_result.value();
// // Use `message`.
// ```
// Note, almost all of the implementation of this class is
// in fact in rust code behind a FFI-able C ABI. One should
// normally not need to look under the hood if all you want is to test
// the interaction with your code with this library. This means, if it does
// not support something you need, filing a bug at may be
// the fastest way to get what you need.
#include <lib/fit/result.h>
#include <memory>
#include <string>
#include "gtest/gtest_prod.h"
#include "src/lib/intl/lookup/rust/lookup.h"
namespace intl {
// The C++ API used to look up localized messages by their unique message ID.
// See the top of this header file for use examples.
class Lookup {
// Error codes reported by New() and Lookup() methods.
enum class Status : int8_t {
// No error.
OK = 0,
// The value requested is not available.
// The argument passed in by the user is not valid.
// Some internal error happened = -1, Consult logs for details.
// Makes a new lookup object, which contains information about the passed-in
// locales. At present, if any one of the locales is not present verbatim,
// an error is returned.
// Errors:
// - UNAVAILABLE: one of the requested locale IDs is not avalable for use.
// - ARGUMENT_ERROR: the locales ids are malfomed, e.g. nonexistent, or
// not a valid UTF8 encoding of the locale ID.
static fit::result<std::unique_ptr<Lookup>, Lookup::Status> New(
const std::vector<std::string>& locale_ids);
// Looks up the message by its unique `message_id`.
// Errors:
// - UNAVAILABLE: the requested message ID is not present in the loaded
// resource bundle.
fit::result<std::string_view, Lookup::Status> String(uint64_t message_id);
// Instantiates a fake Lookup instance, which is useful for tests that don't
// want to make a full end-to-end localization setup.
// The fake is simplistic and it is the intention that it provides you with
// some default fake behaviors. The behaviors are as follows at the moment,
// and more could be added if needed.
// - If `locale_ids` contains the string `en-US`, the constructor will
// return UNAVAILABLE.
// - If the message ID pased to `Lookup::String()` is exactly 1, the fake
// returns `Hello, {person}!`, so that you can test 1-parameter formatting.
// - Otherwise, for an even mesage ID it returns "Hello world!", or for
// an odd message ID returns UNAVAILABLE.
// The implementation of the fake itself is done in rust behind a FFI ABI,
// see the package //src/lib/intl/lookup/rust for details.
static fit::result<std::unique_ptr<Lookup>, Lookup::Status> NewForTest(
const std::vector<std::string>& locale_ids);
// Same as above, except allows you to pass in custom behavior operations
// for the fake and affect its behavior. As a user of this library you should
// normally never need to use this particular constructor. If you need
// special behavior, consider filing a feature request instead to component
// "I18N>Localization" at
static fit::result<std::unique_ptr<Lookup>, Lookup::Status> NewForTest(
const std::vector<std::string>& locale_ids, const intl_lookup_ops_t ops);
FRIEND_TEST(Intl, CreateError);
FRIEND_TEST(Intl, LookupReturnValues);
// Injects fake operations for testing. Takes ownership of impl.
Lookup(intl_lookup_t* impl, intl_lookup_ops_t ops_for_test);
// Operations used to access the implementation type from the C ABI,
// int_lookup_t*. The ops need to vary only for tests.
const intl_lookup_ops_t ops_;
// Owned by this class. Never null for a properly initialized class.
intl_lookup_t* impl_ = nullptr;
Lookup(const Lookup&) = delete;
Lookup(const Lookup&&) = delete;
Lookup() = delete;
}; // namespace intl