1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #ifndef intl_components_DateTimePart_h_
5 #define intl_components_DateTimePart_h_
6 
7 #include <cstddef>
8 #include <cstdint>
9 
10 #include "mozilla/Vector.h"
11 
12 namespace mozilla::intl {
13 
14 enum class DateTimePartType : int16_t {
15   Literal,
16   Weekday,
17   Era,
18   Year,
19   YearName,
20   RelatedYear,
21   Month,
22   Day,
23   DayPeriod,
24   Hour,
25   Minute,
26   Second,
27   FractionalSecondDigits,
28   TimeZoneName,
29   Unknown
30 };
31 
32 enum class DateTimePartSource : int16_t { Shared, StartRange, EndRange };
33 
34 /**
35  * The 'Part' object defined in FormatDateTimeToParts and
36  * FormatDateTimeRangeToParts
37  *
38  * Each part consists of three properties: ||Type||, ||Value|| and ||Source||,
39  * with the ||Source|| property is set to DateTimePartSource::Shared by default.
40  * (Note: From the spec, the part from FormatDateTimeToParts doesn't have the
41  * ||Source|| property, so if the caller is FormatDateTimeToParts, it should
42  * ignore the ||Source|| property).
43  *
44  * To store DateTimePart more efficiently, it doesn't store the ||Value|| of
45  * type string in this struct. Instead, it stores the end index of the string
46  * in the buffer(which is passed to DateTimeFormat::TryFormatToParts() or
47  * can be got by calling AutoFormattedDateInterval::ToSpan()). The begin index
48  * of the ||Value|| is the mEndIndex of the previous part.
49  *
50  *  Buffer
51  *  0               i                j
52  * +---------------+---------------+---------------+
53  * | Part[0].Value | Part[1].Value | Part[2].Value | ....
54  * +---------------+---------------+---------------+
55  *
56  *     Part[0].mEndIndex is i. Part[0].Value is stored in the Buffer[0..i].
57  *     Part[1].mEndIndex is j. Part[1].Value is stored in the Buffer[i..j].
58  *
59  * See:
60  * https://tc39.es/ecma402/#sec-formatdatetimetoparts
61  * https://tc39.es/ecma402/#sec-formatdatetimerangetoparts
62  */
63 struct DateTimePart {
DateTimePartDateTimePart64   DateTimePart(DateTimePartType type, size_t endIndex,
65                DateTimePartSource source)
66       : mEndIndex(endIndex), mType(type), mSource(source) {}
67 
68   // See the above comments for details, mEndIndex is placed first for reducing
69   // padding.
70   size_t mEndIndex;
71   DateTimePartType mType;
72   DateTimePartSource mSource;
73 };
74 
75 // The common parts are 'month', 'literal', 'day', 'literal', 'year', 'literal',
76 // 'hour', 'literal', 'minute', 'literal', which are 10 parts, for DateTimeRange
77 // the number will be doubled, so choosing 32 as the initial length to prevent
78 // heap allocation.
79 constexpr size_t INITIAL_DATETIME_PART_VECTOR_SIZE = 32;
80 using DateTimePartVector =
81     mozilla::Vector<DateTimePart, INITIAL_DATETIME_PART_VECTOR_SIZE>;
82 
83 }  // namespace mozilla::intl
84 #endif
85