зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1734932 - Add intl::NumberParser; r=platform-i18n-reviewers,gregtatum
Awkwardly, this relies upon a different ICU4C NumberFormat API than the existing intl::NumberFormat implementation, so it seems best to have this live in a separate class. Differential Revision: https://phabricator.services.mozilla.com/D133124
This commit is contained in:
Родитель
179adccae9
Коммит
8e4b11994a
|
@ -0,0 +1,34 @@
|
|||
/* 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/. */
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/intl/NumberParser.h"
|
||||
|
||||
namespace mozilla::intl {
|
||||
|
||||
TEST(IntlNumberParser, Basic)
|
||||
{
|
||||
// Try with an English locale
|
||||
UniquePtr<NumberParser> np = NumberParser::TryCreate("en-US", true).unwrap();
|
||||
auto result = np->ParseDouble(MakeStringSpan(u"1,234.56"));
|
||||
ASSERT_TRUE(result.isOk());
|
||||
ASSERT_EQ(result.unwrap().first, 1234.56);
|
||||
ASSERT_EQ(result.unwrap().second, 8);
|
||||
|
||||
// Disable grouping, parsing will stop at the first comma
|
||||
np = NumberParser::TryCreate("en-US", false).unwrap();
|
||||
result = np->ParseDouble(MakeStringSpan(u"1,234.56"));
|
||||
ASSERT_TRUE(result.isOk());
|
||||
ASSERT_EQ(result.unwrap().first, 1);
|
||||
ASSERT_EQ(result.unwrap().second, 1);
|
||||
|
||||
// Try with a Spanish locale
|
||||
np = NumberParser::TryCreate("es-CR", true).unwrap();
|
||||
result = np->ParseDouble(MakeStringSpan(u"1234,56"));
|
||||
ASSERT_TRUE(result.isOk());
|
||||
ASSERT_EQ(result.unwrap().first, 1234.56);
|
||||
ASSERT_EQ(result.unwrap().second, 7);
|
||||
}
|
||||
|
||||
} // namespace mozilla::intl
|
|
@ -18,6 +18,7 @@ UNIFIED_SOURCES += [
|
|||
"TestMeasureUnit.cpp",
|
||||
"TestNumberFormat.cpp",
|
||||
"TestNumberingSystem.cpp",
|
||||
"TestNumberParser.cpp",
|
||||
"TestPluralRules.cpp",
|
||||
"TestRelativeTimeFormat.cpp",
|
||||
"TestScript.cpp",
|
||||
|
|
|
@ -25,6 +25,7 @@ EXPORTS.mozilla.intl = [
|
|||
"src/MeasureUnit.h",
|
||||
"src/NumberFormat.h",
|
||||
"src/NumberingSystem.h",
|
||||
"src/NumberParser.h",
|
||||
"src/NumberPart.h",
|
||||
"src/NumberRangeFormat.h",
|
||||
"src/PluralRules.h",
|
||||
|
@ -57,6 +58,7 @@ UNIFIED_SOURCES += [
|
|||
"src/NumberFormatFields.cpp",
|
||||
"src/NumberFormatterSkeleton.cpp",
|
||||
"src/NumberingSystem.cpp",
|
||||
"src/NumberParser.cpp",
|
||||
"src/NumberRangeFormat.cpp",
|
||||
"src/PluralRules.cpp",
|
||||
"src/RelativeTimeFormat.cpp",
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/* 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/. */
|
||||
#include "mozilla/intl/NumberParser.h"
|
||||
|
||||
namespace mozilla::intl {
|
||||
|
||||
/*static*/ Result<UniquePtr<NumberParser>, ICUError> NumberParser::TryCreate(
|
||||
const char* aLocale, bool aUseGrouping) {
|
||||
UniquePtr<NumberParser> nf = MakeUnique<NumberParser>();
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
nf->mNumberFormat =
|
||||
unum_open(UNUM_DECIMAL, nullptr, 0, aLocale, nullptr, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
return Err(ToICUError(status));
|
||||
}
|
||||
|
||||
if (!aUseGrouping) {
|
||||
unum_setAttribute(nf->mNumberFormat.GetMut(), UNUM_GROUPING_USED, UBool(0));
|
||||
}
|
||||
|
||||
return nf;
|
||||
}
|
||||
|
||||
NumberParser::~NumberParser() {
|
||||
if (mNumberFormat) {
|
||||
unum_close(mNumberFormat.GetMut());
|
||||
}
|
||||
}
|
||||
|
||||
Result<std::pair<double, int32_t>, ICUError> NumberParser::ParseDouble(
|
||||
Span<const char16_t> aDouble) const {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t parsePos = 0;
|
||||
double value = unum_parseDouble(mNumberFormat.GetConst(), aDouble.data(),
|
||||
static_cast<int32_t>(aDouble.size()),
|
||||
&parsePos, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
return Err(ToICUError(status));
|
||||
}
|
||||
return std::make_pair(value, parsePos);
|
||||
}
|
||||
|
||||
} // namespace mozilla::intl
|
|
@ -0,0 +1,46 @@
|
|||
/* 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 intl_components_NumberParser_h_
|
||||
#define intl_components_NumberParser_h_
|
||||
|
||||
#include "mozilla/intl/ICUError.h"
|
||||
#include "mozilla/intl/ICU4CGlue.h"
|
||||
#include "mozilla/Span.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "unicode/unum.h"
|
||||
|
||||
namespace mozilla::intl {
|
||||
|
||||
class NumberParser {
|
||||
public:
|
||||
/**
|
||||
* Initialize a new NumberParser for the provided locale and using the
|
||||
* provided options.
|
||||
*/
|
||||
static Result<UniquePtr<NumberParser>, ICUError> TryCreate(
|
||||
const char* aLocale, bool aUseGrouping);
|
||||
|
||||
NumberParser() : mNumberFormat(nullptr){};
|
||||
NumberParser(const NumberParser&) = delete;
|
||||
NumberParser& operator=(const NumberParser&) = delete;
|
||||
~NumberParser();
|
||||
|
||||
/**
|
||||
* Attempts to parse a string representing a double, returning the parsed
|
||||
* double and the parse position if successful, or an error.
|
||||
*
|
||||
* The parse position is the index into the input string where parsing
|
||||
* stopped because an non-numeric character was encountered.
|
||||
*/
|
||||
Result<std::pair<double, int32_t>, ICUError> ParseDouble(
|
||||
Span<const char16_t> aDouble) const;
|
||||
|
||||
private:
|
||||
ICUPointer<UNumberFormat> mNumberFormat;
|
||||
};
|
||||
|
||||
} // namespace mozilla::intl
|
||||
|
||||
#endif
|
Загрузка…
Ссылка в новой задаче