summaryrefslogtreecommitdiffstats
path: root/intl/components/src/NumberFormatFields.h
blob: 4f05d4e98b7830eae6efbfbdb512ae59b95c8896 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* 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_NumberFormatFields_h_
#define intl_components_NumberFormatFields_h_
#include "mozilla/intl/ICUError.h"
#include "mozilla/intl/NumberPart.h"
#include "mozilla/Maybe.h"
#include "mozilla/Result.h"
#include "mozilla/Vector.h"

#include "unicode/unum.h"

struct UFormattedNumber;
struct UFormattedValue;

namespace mozilla::intl {

struct NumberFormatField {
  uint32_t begin;
  uint32_t end;
  NumberPartType type;

  // Needed for vector-resizing scratch space.
  NumberFormatField() = default;

  NumberFormatField(uint32_t begin, uint32_t end, NumberPartType type)
      : begin(begin), end(end), type(type) {}
};

struct NumberPartSourceMap {
  struct Range {
    uint32_t begin = 0;
    uint32_t end = 0;
  };

  // Begin and end position of the start range.
  Range start;

  // Begin and end position of the end range.
  Range end;

  NumberPartSource source(uint32_t endIndex) {
    if (start.begin < endIndex && endIndex <= start.end) {
      return NumberPartSource::Start;
    }
    if (end.begin < endIndex && endIndex <= end.end) {
      return NumberPartSource::End;
    }
    return NumberPartSource::Shared;
  }

  NumberPartSource source(const NumberFormatField& field) {
    return source(field.end);
  }
};

class NumberFormatFields {
  using FieldsVector = Vector<NumberFormatField, 16>;

  FieldsVector fields_;

 public:
  [[nodiscard]] bool append(NumberPartType type, int32_t begin, int32_t end);

  [[nodiscard]] bool toPartsVector(size_t overallLength,
                                   NumberPartVector& parts) {
    return toPartsVector(overallLength, {}, parts);
  }

  [[nodiscard]] bool toPartsVector(size_t overallLength,
                                   const NumberPartSourceMap& sourceMap,
                                   NumberPartVector& parts);
};

Result<std::u16string_view, ICUError> FormatResultToParts(
    const UFormattedNumber* value, Maybe<double> number, bool isNegative,
    bool formatForUnit, NumberPartVector& parts);

Result<std::u16string_view, ICUError> FormatResultToParts(
    const UFormattedValue* value, Maybe<double> number, bool isNegative,
    bool formatForUnit, NumberPartVector& parts);

Maybe<NumberPartType> GetPartTypeForNumberField(UNumberFormatFields fieldName,
                                                Maybe<double> number,
                                                bool isNegative,
                                                bool formatForUnit);

}  // namespace mozilla::intl

#endif