/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef builtin_intl_ParameterNegotiation_h #define builtin_intl_ParameterNegotiation_h #include "mozilla/Assertions.h" #include "mozilla/Maybe.h" #include "mozilla/Span.h" #include "mozilla/Variant.h" #include #include #include #include #include #include "js/friend/ErrorMessages.h" #include "js/RootingAPI.h" #include "js/TypeDecls.h" #include "vm/StringType.h" namespace js::intl { /** * Pair representing options and their corresponding names. */ template using OptionValues = std::pair, std::array>; /** * Apply the function `F` on each element of `args` and then return the inputs * and results as a pair of arrays. */ template constexpr auto MapOptions(auto... args) { return std::pair{std::array{(args)...}, std::array{F(args)...}}; } namespace detail { /** * GetOption ( options, property, type, values, default ) * * Read the property `property' from `options`, convert it to a string, and then * compare this string against `values`. If the string was found in `values`, * return its index. Otherwise return an index larger than the size of `values`. */ bool GetStringOption(JSContext* cx, JS::Handle options, JS::Handle property, mozilla::Span values, JSErrNum errorNumber, size_t* result); } // namespace detail /** * GetOption ( options, property, type, values, default ) * * Read the property `property' from `options`, convert it to a string, and then * compare it against the option values in `values`. If no matching option was * found, return `defaultValue`. */ template inline bool GetStringOption(JSContext* cx, JS::Handle options, JS::Handle property, const OptionValues& values, Option defaultValue, JSErrNum errorNumber, Option* result) { size_t index; if (!detail::GetStringOption(cx, options, property, values.second, errorNumber, &index)) { return false; } if (index < N) { *result = values.first[index]; } else { *result = defaultValue; } return true; } /** * GetOption ( options, property, type, values, default ) * * Read the property `property' from `options`, convert it to a string, and then * compare it against the option values in `values`. If no matching option was * found, return `defaultValue`. */ template inline bool GetStringOption(JSContext* cx, JS::Handle options, JS::Handle property, const OptionValues& values, Option defaultValue, Option* result) { return GetStringOption(cx, options, property, values, defaultValue, JSMSG_INVALID_OPTION_VALUE, result); } /** * GetOption ( options, property, type, values, default ) * * Read the property `property' from `options`, convert it to a string, and then * compare it against the option values in `values`. If no matching option was * found, return `mozilla::Nothing()`. */ template inline bool GetStringOption(JSContext* cx, JS::Handle options, JS::Handle property, const OptionValues& values, mozilla::Maybe