Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1051)

Side by Side Diff: components/payments/currency_formatter.cc

Issue 2621033003: [Payments] Currency formatter for order amounts. (Closed)
Patch Set: Initial Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/payments/currency_formatter.h"
6
7 #include <memory>
8
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "third_party/icu/source/common/unicode/unistr.h"
12 #include "third_party/icu/source/common/unicode/utypes.h"
13 #include "third_party/icu/source/i18n/unicode/numfmt.h"
14
15 namespace payments {
16
17 namespace {
18
19 // Max currency code length. Length of currency code can be at most 2048.
20 const static size_t kMaxCurrencyCodeLength = 2048;
21
22 } // namespace
23
24 const std::string FormatAmountForCurrency(const std::string& amount,
25 const std::string& currency_code,
26 const icu::Locale& locale) {
27 // Lightweight validation first, checking for basic parameter validity.
28 if (currency_code.empty() || currency_code.size() > kMaxCurrencyCodeLength) {
29 LOG(ERROR) << "Invalid currency code length: " << currency_code;
30 return amount;
31 }
32 double amount_double = 0.0;
please use gerrit instead 2017/01/11 18:29:30 Do you think it may be better to not parse the "am
Mathieu 2017/01/11 22:22:25 I would think base::StringToDouble does the right
33 if (!base::StringToDouble(amount, &amount_double)) {
34 LOG(ERROR) << "Could not convert currency amount to double: " << amount;
35 return amount;
36 }
37
38 UErrorCode ignored = U_ZERO_ERROR;
39 std::unique_ptr<icu::NumberFormat> fmt(
40 icu::NumberFormat::createCurrencyInstance(locale, ignored));
please use gerrit instead 2017/01/11 18:29:30 Why ignore the error?
Mathieu 2017/01/11 22:22:25 a null result is ultimately returned when there is
41 if (!fmt) {
42 icu::UnicodeString name;
43 std::string locale_name;
44 locale.getDisplayName(name).toUTF8String(locale_name);
45 LOG(ERROR) << "Failed to initialize the currency formatter for "
46 << locale_name;
47 return amount;
48 }
49
50 icu::UnicodeString u_currency_code(currency_code.c_str(),
51 currency_code.length());
52 UErrorCode error_code = U_ZERO_ERROR;
53 fmt->setCurrency(u_currency_code.getBuffer(), error_code);
54 if (U_FAILURE(error_code)) {
55 LOG(ERROR) << "Could not set currency on amount formatter: "
please use gerrit instead 2017/01/11 18:29:30 Will print an error for non-ISO currency codes? An
Mathieu 2017/01/11 22:22:26 I've changed currency code handling. This function
56 << currency_code;
57 return amount;
58 }
59
60 icu::UnicodeString output;
61 fmt->format(amount_double, output);
62
63 if (!output.isEmpty()) {
please use gerrit instead 2017/01/11 18:29:30 If the output is empty, you should probably return
Mathieu 2017/01/11 22:22:25 Done. fair enough!
64 // Explicitely removes the currency code (truncated to its 3-letter and
please use gerrit instead 2017/01/11 18:29:30 Explicitly
Mathieu 2017/01/11 22:22:26 Done.
65 // 2-letter versions) from the output, because the payments implementation
66 // explicitely displays it alongside this result.
67 //
68 // 3+ letters: If currency code is "ABCDEF" or "BTX", this code will
69 // transform
70 // "ABC55.00"/"BTX55.00" to "55.00".
71 // 2 letters: If currency code is "CAD", this code will transform "CA$55.00"
72 // to "$55.00" (en_US) or "55,00 $ CA" to "55,00 $" (fr_FR).
73 u_currency_code.truncate(3);
74 output.findAndReplace(u_currency_code, "");
75 u_currency_code.truncate(2);
76 output.findAndReplace(u_currency_code, "");
77 // Trims any unicode whitespace (including non-breaking space).
please use gerrit instead 2017/01/11 18:29:30 base::TrimeWhitespace?
Mathieu 2017/01/11 22:22:26 Does not handle unicode non-breaking space trimmin
78 if (u_isUWhiteSpace(output[0])) {
79 output.remove(0, 1);
80 }
81 if (u_isUWhiteSpace(output[output.length() - 1])) {
82 output.remove(output.length() - 1, 1);
83 }
84 }
85
86 std::string output_str;
87 output.toUTF8String(output_str);
88 return output_str;
89 }
90
91 } // namespace payments
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698