@itwin/core-quantity 3.1.0-dev.8 → 3.2.0-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -1
- package/lib/cjs/Exception.d.ts.map +1 -1
- package/lib/cjs/Exception.js +1 -0
- package/lib/cjs/Exception.js.map +1 -1
- package/lib/cjs/Formatter/Format.d.ts +37 -41
- package/lib/cjs/Formatter/Format.d.ts.map +1 -1
- package/lib/cjs/Formatter/Format.js +117 -341
- package/lib/cjs/Formatter/Format.js.map +1 -1
- package/lib/cjs/Formatter/FormatEnums.d.ts +46 -1
- package/lib/cjs/Formatter/FormatEnums.d.ts.map +1 -1
- package/lib/cjs/Formatter/FormatEnums.js +219 -2
- package/lib/cjs/Formatter/FormatEnums.js.map +1 -1
- package/lib/cjs/Formatter/FormatterSpec.js +1 -1
- package/lib/cjs/Formatter/FormatterSpec.js.map +1 -1
- package/lib/cjs/Interfaces.d.ts +9 -1
- package/lib/cjs/Interfaces.d.ts.map +1 -1
- package/lib/cjs/Interfaces.js.map +1 -1
- package/lib/esm/Exception.d.ts.map +1 -1
- package/lib/esm/Exception.js +2 -1
- package/lib/esm/Exception.js.map +1 -1
- package/lib/esm/Formatter/Format.d.ts +37 -41
- package/lib/esm/Formatter/Format.d.ts.map +1 -1
- package/lib/esm/Formatter/Format.js +116 -341
- package/lib/esm/Formatter/Format.js.map +1 -1
- package/lib/esm/Formatter/FormatEnums.d.ts +46 -1
- package/lib/esm/Formatter/FormatEnums.d.ts.map +1 -1
- package/lib/esm/Formatter/FormatEnums.js +205 -1
- package/lib/esm/Formatter/FormatEnums.js.map +1 -1
- package/lib/esm/Formatter/FormatterSpec.js +1 -1
- package/lib/esm/Formatter/FormatterSpec.js.map +1 -1
- package/lib/esm/Interfaces.d.ts +9 -1
- package/lib/esm/Interfaces.d.ts.map +1 -1
- package/lib/esm/Interfaces.js.map +1 -1
- package/package.json +5 -5
|
@@ -7,17 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { QuantityConstants } from "../Constants";
|
|
9
9
|
import { QuantityError, QuantityStatus } from "../Exception";
|
|
10
|
-
import { DecimalPrecision, FormatTraits, FormatType,
|
|
10
|
+
import { DecimalPrecision, FormatTraits, formatTraitsToArray, FormatType, formatTypeToString, getTraitString, parseFormatTrait, parseFormatType, parsePrecision, parseScientificType, parseShowSignOption, scientificTypeToString, ShowSignOption, showSignOptionToString } from "./FormatEnums";
|
|
11
11
|
import { isCustomFormatProps } from "./Interfaces";
|
|
12
12
|
// cSpell:ignore ZERONORMALIZED, nosign, onlynegative, signalways, negativeparentheses
|
|
13
13
|
// cSpell:ignore trailzeroes, keepsinglezero, zeroempty, keepdecimalpoint, applyrounding, fractiondash, showunitlabel, prependunitlabel, exponentonlynegative
|
|
14
|
-
/** A class
|
|
14
|
+
/** A base Format class with shared properties and functionality between quantity and ecschema-metadata Format classes
|
|
15
15
|
* @beta
|
|
16
16
|
*/
|
|
17
|
-
export class
|
|
18
|
-
/** Constructor
|
|
19
|
-
* @param name The name of a format specification. TODO: make optional or remove
|
|
20
|
-
*/
|
|
17
|
+
export class BaseFormat {
|
|
21
18
|
constructor(name) {
|
|
22
19
|
this._name = "";
|
|
23
20
|
this._roundFactor = 0.0;
|
|
@@ -28,280 +25,139 @@ export class Format {
|
|
|
28
25
|
this._thousandSeparator = QuantityConstants.LocaleSpecificThousandSeparator;
|
|
29
26
|
this._uomSeparator = " "; // optional; default is " "; defined separator between magnitude and the unit
|
|
30
27
|
this._stationSeparator = "+"; // optional; default is "+"
|
|
31
|
-
this._formatTraits =
|
|
28
|
+
this._formatTraits = FormatTraits.Uninitialized;
|
|
32
29
|
this._spacer = " "; // optional; default is " "
|
|
33
30
|
this._includeZero = true; // optional; default is true
|
|
34
31
|
this._name = name;
|
|
35
32
|
}
|
|
36
33
|
get name() { return this._name; }
|
|
37
34
|
get roundFactor() { return this._roundFactor; }
|
|
35
|
+
set roundFactor(roundFactor) { this._roundFactor = roundFactor; }
|
|
38
36
|
get type() { return this._type; }
|
|
37
|
+
set type(formatType) { this._type = formatType; }
|
|
39
38
|
get precision() { return this._precision; }
|
|
39
|
+
set precision(precision) { this._precision = precision; }
|
|
40
40
|
get minWidth() { return this._minWidth; }
|
|
41
|
+
set minWidth(minWidth) { this._minWidth = minWidth; }
|
|
41
42
|
get scientificType() { return this._scientificType; }
|
|
43
|
+
set scientificType(scientificType) { this._scientificType = scientificType; }
|
|
42
44
|
get showSignOption() { return this._showSignOption; }
|
|
45
|
+
set showSignOption(showSignOption) { this._showSignOption = showSignOption; }
|
|
43
46
|
get decimalSeparator() { return this._decimalSeparator; }
|
|
47
|
+
set decimalSeparator(decimalSeparator) { this._decimalSeparator = decimalSeparator; }
|
|
44
48
|
get thousandSeparator() { return this._thousandSeparator; }
|
|
49
|
+
set thousandSeparator(thousandSeparator) { this._thousandSeparator = thousandSeparator; }
|
|
45
50
|
get uomSeparator() { return this._uomSeparator; }
|
|
51
|
+
set uomSeparator(uomSeparator) { this._uomSeparator = uomSeparator; }
|
|
46
52
|
get stationSeparator() { return this._stationSeparator; }
|
|
53
|
+
set stationSeparator(stationSeparator) { this._stationSeparator = stationSeparator; }
|
|
47
54
|
get stationOffsetSize() { return this._stationOffsetSize; }
|
|
55
|
+
set stationOffsetSize(stationOffsetSize) { stationOffsetSize = this._stationOffsetSize = stationOffsetSize; }
|
|
48
56
|
get formatTraits() { return this._formatTraits; }
|
|
57
|
+
set formatTraits(formatTraits) { this._formatTraits = formatTraits; }
|
|
49
58
|
get spacer() { return this._spacer; }
|
|
59
|
+
set spacer(spacer) { this._spacer = spacer !== null && spacer !== void 0 ? spacer : this._spacer; }
|
|
50
60
|
get includeZero() { return this._includeZero; }
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return "ZeroNormalized";
|
|
61
|
+
set includeZero(includeZero) { this._includeZero = includeZero !== null && includeZero !== void 0 ? includeZero : this._includeZero; }
|
|
62
|
+
/** This method parses input string that is typically extracted for persisted JSON data and validates that the string is a valid FormatType. Throws exception if not valid. */
|
|
63
|
+
parseFormatTraits(formatTraitsFromJson) {
|
|
64
|
+
const formatTraits = (Array.isArray(formatTraitsFromJson)) ? formatTraitsFromJson : formatTraitsFromJson.split(/,|;|\|/);
|
|
65
|
+
formatTraits.forEach((formatTraitsString) => {
|
|
66
|
+
const formatTrait = parseFormatTrait(formatTraitsString, this.name);
|
|
67
|
+
this._formatTraits = this.formatTraits | formatTrait;
|
|
68
|
+
});
|
|
60
69
|
}
|
|
61
|
-
/** This method
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
case "normalized":
|
|
65
|
-
return ScientificType.Normalized;
|
|
66
|
-
case "zeronormalized":
|
|
67
|
-
return ScientificType.ZeroNormalized;
|
|
68
|
-
default:
|
|
69
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${formatName} has an invalid 'SCIENTIFIC_TYPE' attribute.`);
|
|
70
|
-
}
|
|
70
|
+
/** This method returns true if the formatTrait is set in this Format object. */
|
|
71
|
+
hasFormatTraitSet(formatTrait) {
|
|
72
|
+
return (this._formatTraits & formatTrait) === formatTrait;
|
|
71
73
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return "NoSign";
|
|
79
|
-
case ShowSignOption.OnlyNegative:
|
|
80
|
-
return "OnlyNegative";
|
|
81
|
-
case ShowSignOption.SignAlways:
|
|
82
|
-
return "SignAlways";
|
|
74
|
+
loadFormatProperties(formatProps) {
|
|
75
|
+
this._type = parseFormatType(formatProps.type, this.name);
|
|
76
|
+
if (formatProps.precision !== undefined) {
|
|
77
|
+
if (!Number.isInteger(formatProps.precision)) // mut be an integer
|
|
78
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'precision' attribute. It should be an integer.`);
|
|
79
|
+
this._precision = parsePrecision(formatProps.precision, this._type, this.name);
|
|
83
80
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
case "nosign":
|
|
89
|
-
return ShowSignOption.NoSign;
|
|
90
|
-
case "onlynegative":
|
|
91
|
-
return ShowSignOption.OnlyNegative;
|
|
92
|
-
case "signalways":
|
|
93
|
-
return ShowSignOption.SignAlways;
|
|
94
|
-
case "negativeparentheses":
|
|
95
|
-
return ShowSignOption.NegativeParentheses;
|
|
96
|
-
default:
|
|
97
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${formatName} has an invalid 'showSignOption' attribute.`);
|
|
81
|
+
if (this.type === FormatType.Scientific) {
|
|
82
|
+
if (undefined === formatProps.scientificType) // if format type is scientific and scientific type is undefined, throw
|
|
83
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} is 'Scientific' type therefore the attribute 'scientificType' is required.`);
|
|
84
|
+
this._scientificType = parseScientificType(formatProps.scientificType, this.name);
|
|
98
85
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const traitStr = Format.getTraitString(trait);
|
|
105
|
-
return formatTraits.find((traitEntry) => traitStr === traitEntry) ? true : false;
|
|
106
|
-
}
|
|
107
|
-
/** Get string used in FormatProps */
|
|
108
|
-
static getTraitString(trait) {
|
|
109
|
-
switch (trait) {
|
|
110
|
-
case FormatTraits.TrailZeroes:
|
|
111
|
-
return "trailZeroes";
|
|
112
|
-
case FormatTraits.KeepSingleZero:
|
|
113
|
-
return "keepSingleZero";
|
|
114
|
-
case FormatTraits.ZeroEmpty:
|
|
115
|
-
return "zeroEmpty";
|
|
116
|
-
case FormatTraits.KeepDecimalPoint:
|
|
117
|
-
return "keepDecimalPoint";
|
|
118
|
-
case FormatTraits.ApplyRounding:
|
|
119
|
-
return "applyRounding";
|
|
120
|
-
case FormatTraits.FractionDash:
|
|
121
|
-
return "fractionDash";
|
|
122
|
-
case FormatTraits.ShowUnitLabel:
|
|
123
|
-
return "showUnitLabel";
|
|
124
|
-
case FormatTraits.PrependUnitLabel:
|
|
125
|
-
return "prependUnitLabel";
|
|
126
|
-
case FormatTraits.Use1000Separator:
|
|
127
|
-
return "use1000Separator";
|
|
128
|
-
case FormatTraits.ExponentOnlyNegative:
|
|
129
|
-
default:
|
|
130
|
-
return "exponentOnlyNegative";
|
|
86
|
+
if (undefined !== formatProps.roundFactor) { // optional; default is 0.0
|
|
87
|
+
if (typeof (formatProps.roundFactor) !== "number")
|
|
88
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'roundFactor' attribute. It should be of type 'number'.`);
|
|
89
|
+
if (formatProps.roundFactor !== this.roundFactor) // if roundFactor isn't default value of 0.0, reassign roundFactor variable
|
|
90
|
+
this._roundFactor = formatProps.roundFactor;
|
|
131
91
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if ((currentFormatTrait & FormatTraits.TrailZeroes) === FormatTraits.TrailZeroes)
|
|
137
|
-
formatTraitsArr.push(Format.getTraitString(FormatTraits.TrailZeroes));
|
|
138
|
-
if ((currentFormatTrait & FormatTraits.KeepSingleZero) === FormatTraits.KeepSingleZero)
|
|
139
|
-
formatTraitsArr.push(Format.getTraitString(FormatTraits.KeepSingleZero));
|
|
140
|
-
if ((currentFormatTrait & FormatTraits.ZeroEmpty) === FormatTraits.ZeroEmpty)
|
|
141
|
-
formatTraitsArr.push(Format.getTraitString(FormatTraits.ZeroEmpty));
|
|
142
|
-
if ((currentFormatTrait & FormatTraits.KeepDecimalPoint) === FormatTraits.KeepDecimalPoint)
|
|
143
|
-
formatTraitsArr.push(Format.getTraitString(FormatTraits.KeepDecimalPoint));
|
|
144
|
-
if ((currentFormatTrait & FormatTraits.ApplyRounding) === FormatTraits.ApplyRounding)
|
|
145
|
-
formatTraitsArr.push(Format.getTraitString(FormatTraits.ApplyRounding));
|
|
146
|
-
if ((currentFormatTrait & FormatTraits.FractionDash) === FormatTraits.FractionDash)
|
|
147
|
-
formatTraitsArr.push(Format.getTraitString(FormatTraits.FractionDash));
|
|
148
|
-
if ((currentFormatTrait & FormatTraits.ShowUnitLabel) === FormatTraits.ShowUnitLabel)
|
|
149
|
-
formatTraitsArr.push(Format.getTraitString(FormatTraits.ShowUnitLabel));
|
|
150
|
-
if ((currentFormatTrait & FormatTraits.PrependUnitLabel) === FormatTraits.PrependUnitLabel)
|
|
151
|
-
formatTraitsArr.push(Format.getTraitString(FormatTraits.PrependUnitLabel));
|
|
152
|
-
if ((currentFormatTrait & FormatTraits.Use1000Separator) === FormatTraits.Use1000Separator)
|
|
153
|
-
formatTraitsArr.push(Format.getTraitString(FormatTraits.Use1000Separator));
|
|
154
|
-
// NOTE: the formatter does not current use trait ExponentOnlyNegative
|
|
155
|
-
if ((currentFormatTrait & FormatTraits.ExponentOnlyNegative) === FormatTraits.ExponentOnlyNegative)
|
|
156
|
-
formatTraitsArr.push(Format.getTraitString(FormatTraits.ExponentOnlyNegative));
|
|
157
|
-
return formatTraitsArr;
|
|
158
|
-
}
|
|
159
|
-
/** This method parses input string that is typically extracted for persisted JSON data and validates that the string is a valid FormatTrait. Throws exception if not valid. */
|
|
160
|
-
static parseFormatTrait(stringToCheck, currentFormatTrait) {
|
|
161
|
-
switch (stringToCheck.toLowerCase()) {
|
|
162
|
-
case "trailzeroes":
|
|
163
|
-
return currentFormatTrait | FormatTraits.TrailZeroes;
|
|
164
|
-
case "keepsinglezero":
|
|
165
|
-
return currentFormatTrait | FormatTraits.KeepSingleZero; // keep single when format type is Decimal
|
|
166
|
-
case "zeroempty":
|
|
167
|
-
return currentFormatTrait | FormatTraits.ZeroEmpty;
|
|
168
|
-
case "keepdecimalpoint":
|
|
169
|
-
return currentFormatTrait | FormatTraits.KeepDecimalPoint; // add decimal point when no fractional part and format type is Decimal
|
|
170
|
-
case "applyrounding":
|
|
171
|
-
return currentFormatTrait | FormatTraits.ApplyRounding;
|
|
172
|
-
case "fractiondash":
|
|
173
|
-
return currentFormatTrait | FormatTraits.FractionDash;
|
|
174
|
-
case "showunitlabel":
|
|
175
|
-
return currentFormatTrait | FormatTraits.ShowUnitLabel;
|
|
176
|
-
case "prependunitlabel":
|
|
177
|
-
return currentFormatTrait | FormatTraits.PrependUnitLabel;
|
|
178
|
-
case "use1000separator":
|
|
179
|
-
return currentFormatTrait | FormatTraits.Use1000Separator;
|
|
180
|
-
case "exponentonlynegative":
|
|
181
|
-
return currentFormatTrait | FormatTraits.ExponentOnlyNegative;
|
|
182
|
-
default:
|
|
183
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `Format has an invalid 'formatTraits' option.`);
|
|
92
|
+
if (undefined !== formatProps.minWidth) { // optional
|
|
93
|
+
if (!Number.isInteger(formatProps.minWidth) || formatProps.minWidth < 0) // must be a positive int
|
|
94
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'minWidth' attribute. It should be a positive integer.`);
|
|
95
|
+
this._minWidth = formatProps.minWidth;
|
|
184
96
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
let traits = 0;
|
|
192
|
-
for (const traitStr of formatTraits) {
|
|
193
|
-
traits = Format.parseFormatTrait(traitStr, traits);
|
|
97
|
+
if (FormatType.Station === this.type) {
|
|
98
|
+
if (undefined === formatProps.stationOffsetSize)
|
|
99
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} is 'Station' type therefore the attribute 'stationOffsetSize' is required.`);
|
|
100
|
+
if (!Number.isInteger(formatProps.stationOffsetSize) || formatProps.stationOffsetSize < 0) // must be a positive int > 0
|
|
101
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationOffsetSize' attribute. It should be a positive integer.`);
|
|
102
|
+
this._stationOffsetSize = formatProps.stationOffsetSize;
|
|
194
103
|
}
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
return traits;
|
|
198
|
-
}
|
|
199
|
-
/** Method used when generating a JSON object that represents this Format. */
|
|
200
|
-
static formatTypeToString(type) {
|
|
201
|
-
switch (type) {
|
|
202
|
-
case FormatType.Decimal:
|
|
203
|
-
return "Decimal";
|
|
204
|
-
case FormatType.Scientific:
|
|
205
|
-
return "Scientific";
|
|
206
|
-
case FormatType.Station:
|
|
207
|
-
return "Station";
|
|
208
|
-
case FormatType.Fractional:
|
|
209
|
-
return "Fractional";
|
|
104
|
+
if (undefined !== formatProps.showSignOption) { // optional; default is "onlyNegative"
|
|
105
|
+
this._showSignOption = parseShowSignOption(formatProps.showSignOption, this.name);
|
|
210
106
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
case "decimal":
|
|
216
|
-
return FormatType.Decimal;
|
|
217
|
-
case "scientific":
|
|
218
|
-
return FormatType.Scientific;
|
|
219
|
-
case "station":
|
|
220
|
-
return FormatType.Station;
|
|
221
|
-
case "fractional":
|
|
222
|
-
return FormatType.Fractional;
|
|
223
|
-
default:
|
|
224
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${formatName} has an invalid 'type' attribute.`);
|
|
107
|
+
if (undefined !== formatProps.formatTraits && formatProps.formatTraits.length !== 0) { // FormatTraits is optional
|
|
108
|
+
if (!Array.isArray(formatProps.formatTraits) && typeof (formatProps.formatTraits) !== "string") // must be either an array of strings or a string
|
|
109
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'formatTraits' attribute. It should be of type 'string' or 'string[]'.`);
|
|
110
|
+
this.parseFormatTraits(formatProps.formatTraits); // check that all of the options for formatTraits are valid. If now, throw
|
|
225
111
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
case 1:
|
|
233
|
-
return DecimalPrecision.One;
|
|
234
|
-
case 2:
|
|
235
|
-
return DecimalPrecision.Two;
|
|
236
|
-
case 3:
|
|
237
|
-
return DecimalPrecision.Three;
|
|
238
|
-
case 4:
|
|
239
|
-
return DecimalPrecision.Four;
|
|
240
|
-
case 5:
|
|
241
|
-
return DecimalPrecision.Five;
|
|
242
|
-
case 6:
|
|
243
|
-
return DecimalPrecision.Six;
|
|
244
|
-
case 7:
|
|
245
|
-
return DecimalPrecision.Seven;
|
|
246
|
-
case 8:
|
|
247
|
-
return DecimalPrecision.Eight;
|
|
248
|
-
case 9:
|
|
249
|
-
return DecimalPrecision.Nine;
|
|
250
|
-
case 10:
|
|
251
|
-
return DecimalPrecision.Ten;
|
|
252
|
-
case 11:
|
|
253
|
-
return DecimalPrecision.Eleven;
|
|
254
|
-
case 12:
|
|
255
|
-
return DecimalPrecision.Twelve;
|
|
256
|
-
default:
|
|
257
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The 'precision' attribute must be an integer in the range 0-12.`);
|
|
112
|
+
if (undefined !== formatProps.decimalSeparator) { // optional
|
|
113
|
+
if (typeof (formatProps.decimalSeparator) !== "string") // not a string or not a one character string
|
|
114
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'decimalSeparator' attribute. It should be of type 'string'.`);
|
|
115
|
+
if (formatProps.decimalSeparator.length > 1)
|
|
116
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'decimalSeparator' attribute. It should be an empty or one character string.`);
|
|
117
|
+
this._decimalSeparator = formatProps.decimalSeparator;
|
|
258
118
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
case 2:
|
|
266
|
-
return FractionalPrecision.Two;
|
|
267
|
-
case 4:
|
|
268
|
-
return FractionalPrecision.Four;
|
|
269
|
-
case 8:
|
|
270
|
-
return FractionalPrecision.Eight;
|
|
271
|
-
case 16:
|
|
272
|
-
return FractionalPrecision.Sixteen;
|
|
273
|
-
case 32:
|
|
274
|
-
return FractionalPrecision.ThirtyTwo;
|
|
275
|
-
case 64:
|
|
276
|
-
return FractionalPrecision.SixtyFour;
|
|
277
|
-
case 128:
|
|
278
|
-
return FractionalPrecision.OneHundredTwentyEight;
|
|
279
|
-
case 256:
|
|
280
|
-
return FractionalPrecision.TwoHundredFiftySix;
|
|
281
|
-
default:
|
|
282
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${formatName} has an invalid 'precision' attribute.`);
|
|
119
|
+
if (undefined !== formatProps.thousandSeparator) { // optional
|
|
120
|
+
if (typeof (formatProps.thousandSeparator) !== "string")
|
|
121
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'thousandSeparator' attribute. It should be of type 'string'.`);
|
|
122
|
+
if (formatProps.thousandSeparator.length > 1)
|
|
123
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'thousandSeparator' attribute. It should be an empty or one character string.`);
|
|
124
|
+
this._thousandSeparator = formatProps.thousandSeparator;
|
|
283
125
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
126
|
+
if (undefined !== formatProps.uomSeparator) { // optional; default is " "
|
|
127
|
+
if (typeof (formatProps.uomSeparator) !== "string")
|
|
128
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'uomSeparator' attribute. It should be of type 'string'.`);
|
|
129
|
+
if (formatProps.uomSeparator.length < 0 || formatProps.uomSeparator.length > 1)
|
|
130
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'uomSeparator' attribute. It should be an empty or one character string.`);
|
|
131
|
+
this._uomSeparator = formatProps.uomSeparator;
|
|
132
|
+
}
|
|
133
|
+
if (undefined !== formatProps.stationSeparator) { // optional; default is "+"
|
|
134
|
+
if (typeof (formatProps.stationSeparator) !== "string")
|
|
135
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationSeparator' attribute. It should be of type 'string'.`);
|
|
136
|
+
if (formatProps.stationSeparator.length > 1)
|
|
137
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationSeparator' attribute. It should be an empty or one character string.`);
|
|
138
|
+
this._stationSeparator = formatProps.stationSeparator;
|
|
294
139
|
}
|
|
295
140
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
141
|
+
}
|
|
142
|
+
/** A class used to define the specifications for formatting quantity values. This class is typically loaded by reading [[FormatProps]].
|
|
143
|
+
* @beta
|
|
144
|
+
*/
|
|
145
|
+
export class Format extends BaseFormat {
|
|
146
|
+
/** Constructor
|
|
147
|
+
* @param name The name of a format specification. TODO: make optional or remove
|
|
148
|
+
*/
|
|
149
|
+
constructor(name) {
|
|
150
|
+
super(name);
|
|
301
151
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
152
|
+
get units() { return this._units; }
|
|
153
|
+
get hasUnits() { return this._units !== undefined && this._units.length > 0; }
|
|
154
|
+
get customProps() { return this._customProps; }
|
|
155
|
+
static isFormatTraitSetInProps(formatProps, trait) {
|
|
156
|
+
if (!formatProps.formatTraits)
|
|
157
|
+
return false;
|
|
158
|
+
const formatTraits = Array.isArray(formatProps.formatTraits) ? formatProps.formatTraits : formatProps.formatTraits.split(/,|;|\|/);
|
|
159
|
+
const traitStr = getTraitString(trait);
|
|
160
|
+
return formatTraits.find((traitEntry) => traitStr === traitEntry) ? true : false;
|
|
305
161
|
}
|
|
306
162
|
async createUnit(unitsProvider, name, label) {
|
|
307
163
|
if (name === undefined || typeof (name) !== "string" || (label !== undefined && typeof (label) !== "string")) // throws if name is undefined or name isn't a string or if label is defined and isn't a string
|
|
@@ -350,7 +206,7 @@ export class Format {
|
|
|
350
206
|
newFormat._type = options.type;
|
|
351
207
|
if (undefined !== (options === null || options === void 0 ? void 0 : options.precision)) {
|
|
352
208
|
// ensure specified precision is valid
|
|
353
|
-
const precision =
|
|
209
|
+
const precision = parsePrecision(options === null || options === void 0 ? void 0 : options.precision, newFormat._type, newFormat.name);
|
|
354
210
|
newFormat._precision = precision;
|
|
355
211
|
}
|
|
356
212
|
if (undefined !== (options === null || options === void 0 ? void 0 : options.primaryUnit)) {
|
|
@@ -366,94 +222,13 @@ export class Format {
|
|
|
366
222
|
}
|
|
367
223
|
return newFormat;
|
|
368
224
|
}
|
|
369
|
-
loadFormatProperties(jsonObj) {
|
|
370
|
-
if (isCustomFormatProps(jsonObj))
|
|
371
|
-
this._customProps = jsonObj.custom;
|
|
372
|
-
if (undefined === jsonObj.type) // type is required
|
|
373
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} does not have the required 'type' attribute.`);
|
|
374
|
-
if (typeof (jsonObj.type) !== "string")
|
|
375
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'type' attribute. It should be of type 'string'.`);
|
|
376
|
-
this._type = Format.parseFormatType(jsonObj.type, this.name);
|
|
377
|
-
if (undefined === jsonObj.precision) // precision is required
|
|
378
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} does not have the required 'precision' attribute.`);
|
|
379
|
-
else if (typeof (jsonObj.precision) !== "number") // must be a number
|
|
380
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'precision' attribute. It should be of type 'number'.`);
|
|
381
|
-
else if (!Number.isInteger(jsonObj.precision)) // must be an integer
|
|
382
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'precision' attribute. It should be an integer.`);
|
|
383
|
-
this._precision = Format.parsePrecision(jsonObj.precision, this.name, this._type);
|
|
384
|
-
if (this.type === FormatType.Scientific) {
|
|
385
|
-
if (undefined === jsonObj.scientificType) // if format type is scientific and scientific type is undefined, throw
|
|
386
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has type 'Scientific' therefore attribute 'scientificType' is required.`);
|
|
387
|
-
if (typeof (jsonObj.scientificType) !== "string")
|
|
388
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'scientificType' attribute. It should be of type 'string'.`);
|
|
389
|
-
this._scientificType = Format.parseScientificType(jsonObj.scientificType.toLowerCase(), this.name);
|
|
390
|
-
}
|
|
391
|
-
if (this.type === FormatType.Station) {
|
|
392
|
-
if (undefined === jsonObj.stationOffsetSize)
|
|
393
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has type 'Station' therefore attribute 'stationOffsetSize' is required.`);
|
|
394
|
-
if (typeof (jsonObj.stationOffsetSize) !== "number")
|
|
395
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationOffsetSize' attribute. It should be of type 'number'.`);
|
|
396
|
-
if (!Number.isInteger(jsonObj.stationOffsetSize) || jsonObj.stationOffsetSize <= 0) // must be a positive int > 0
|
|
397
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationOffsetSize' attribute. It should be a positive integer.`);
|
|
398
|
-
this._stationOffsetSize = jsonObj.stationOffsetSize;
|
|
399
|
-
}
|
|
400
|
-
if (undefined !== jsonObj.roundFactor) { // optional; default is 0.0
|
|
401
|
-
if (typeof (jsonObj.roundFactor) !== "number")
|
|
402
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'roundFactor' attribute. It should be of type 'number'.`);
|
|
403
|
-
if (jsonObj.roundFactor !== this.roundFactor) // if roundFactor isn't default value of 0.0, reassign roundFactor variable
|
|
404
|
-
this._roundFactor = jsonObj.roundFactor;
|
|
405
|
-
}
|
|
406
|
-
if (undefined !== jsonObj.minWidth) { // optional
|
|
407
|
-
if (typeof (jsonObj.minWidth) !== "number")
|
|
408
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'minWidth' attribute. It should be of type 'number'.`);
|
|
409
|
-
if (!Number.isInteger(jsonObj.minWidth) || jsonObj.minWidth < 0) // must be a positive int
|
|
410
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'minWidth' attribute. It should be a positive integer.`);
|
|
411
|
-
this._minWidth = jsonObj.minWidth;
|
|
412
|
-
}
|
|
413
|
-
if (undefined !== jsonObj.showSignOption) { // optional; default is "onlyNegative"
|
|
414
|
-
if (typeof (jsonObj.showSignOption) !== "string")
|
|
415
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'showSignOption' attribute. It should be of type 'string'.`);
|
|
416
|
-
this._showSignOption = Format.parseShowSignOption(jsonObj.showSignOption, this.name);
|
|
417
|
-
}
|
|
418
|
-
if (undefined !== jsonObj.formatTraits && jsonObj.formatTraits.length !== 0) { // FormatTraits is optional
|
|
419
|
-
if (!Array.isArray(jsonObj.formatTraits) && typeof (jsonObj.formatTraits) !== "string") // must be either an array of strings or a string
|
|
420
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'formatTraits' attribute. It should be of type 'string' or 'string[]'.`);
|
|
421
|
-
this.verifyFormatTraitsOptions(jsonObj.formatTraits); // check that all of the options for formatTraits are valid. If now, throw
|
|
422
|
-
}
|
|
423
|
-
if (undefined !== jsonObj.decimalSeparator) { // optional
|
|
424
|
-
if (typeof (jsonObj.decimalSeparator) !== "string") // not a string or not a one character string
|
|
425
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'decimalSeparator' attribute. It should be of type 'string'.`);
|
|
426
|
-
if (jsonObj.decimalSeparator.length !== 1)
|
|
427
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'decimalSeparator' attribute. It must be a one character string.`);
|
|
428
|
-
this._decimalSeparator = jsonObj.decimalSeparator;
|
|
429
|
-
}
|
|
430
|
-
if (undefined !== jsonObj.thousandSeparator) { // optional
|
|
431
|
-
if (typeof (jsonObj.thousandSeparator) !== "string")
|
|
432
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'thousandSeparator' attribute. It should be of type 'string'.`);
|
|
433
|
-
if (jsonObj.thousandSeparator.length !== 1)
|
|
434
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'thousandSeparator' attribute. It must be a one character string.`);
|
|
435
|
-
this._thousandSeparator = jsonObj.thousandSeparator;
|
|
436
|
-
}
|
|
437
|
-
if (undefined !== jsonObj.uomSeparator) { // optional; default is " "
|
|
438
|
-
if (typeof (jsonObj.uomSeparator) !== "string")
|
|
439
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'uomSeparator' attribute. It should be of type 'string'.`);
|
|
440
|
-
if (jsonObj.uomSeparator.length < 0 || jsonObj.uomSeparator.length > 1)
|
|
441
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'uomSeparator' attribute. It must be empty or a string with a single character.`);
|
|
442
|
-
this._uomSeparator = jsonObj.uomSeparator;
|
|
443
|
-
}
|
|
444
|
-
if (undefined !== jsonObj.stationSeparator) { // optional; default is "+"
|
|
445
|
-
if (typeof (jsonObj.stationSeparator) !== "string")
|
|
446
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationSeparator' attribute. It should be of type 'string'.`);
|
|
447
|
-
if (jsonObj.stationSeparator.length !== 1)
|
|
448
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has an invalid 'stationSeparator' attribute. It must be a one character string.`);
|
|
449
|
-
this._stationSeparator = jsonObj.stationSeparator;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
225
|
/**
|
|
453
226
|
* Populates this Format with the values from the provided.
|
|
454
227
|
*/
|
|
455
228
|
async fromJSON(unitsProvider, jsonObj) {
|
|
456
229
|
this.loadFormatProperties(jsonObj);
|
|
230
|
+
if (isCustomFormatProps(jsonObj))
|
|
231
|
+
this._customProps = jsonObj.custom;
|
|
457
232
|
if (undefined !== jsonObj.composite) { // optional
|
|
458
233
|
this._units = new Array();
|
|
459
234
|
if (jsonObj.composite.includeZero !== undefined) {
|
|
@@ -464,8 +239,8 @@ export class Format {
|
|
|
464
239
|
if (jsonObj.composite.spacer !== undefined) { // spacer must be a string IF it is defined
|
|
465
240
|
if (typeof (jsonObj.composite.spacer) !== "string")
|
|
466
241
|
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has a Composite with an invalid 'spacer' attribute. It must be of type 'string'.`);
|
|
467
|
-
if (jsonObj.composite.spacer.length
|
|
468
|
-
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has a Composite with an invalid 'spacer' attribute. It
|
|
242
|
+
if (jsonObj.composite.spacer.length > 1)
|
|
243
|
+
throw new QuantityError(QuantityStatus.InvalidJson, `The Format ${this.name} has a Composite with an invalid 'spacer' attribute. It should be an empty or one character string.`);
|
|
469
244
|
this._spacer = jsonObj.composite.spacer;
|
|
470
245
|
}
|
|
471
246
|
if (jsonObj.composite.units !== undefined) { // if composite is defined, it must be an array with 1-4 units
|
|
@@ -515,32 +290,32 @@ export class Format {
|
|
|
515
290
|
}
|
|
516
291
|
if (this.customProps)
|
|
517
292
|
return {
|
|
518
|
-
type:
|
|
293
|
+
type: formatTypeToString(this.type),
|
|
519
294
|
precision: this.precision,
|
|
520
295
|
roundFactor: this.roundFactor,
|
|
521
296
|
minWidth: this.minWidth,
|
|
522
|
-
showSignOption:
|
|
523
|
-
formatTraits:
|
|
297
|
+
showSignOption: showSignOptionToString(this.showSignOption),
|
|
298
|
+
formatTraits: formatTraitsToArray(this.formatTraits),
|
|
524
299
|
decimalSeparator: this.decimalSeparator,
|
|
525
300
|
thousandSeparator: this.thousandSeparator,
|
|
526
301
|
uomSeparator: this.uomSeparator,
|
|
527
|
-
scientificType: this.scientificType ?
|
|
302
|
+
scientificType: this.scientificType ? scientificTypeToString(this.scientificType) : undefined,
|
|
528
303
|
stationOffsetSize: this.stationOffsetSize,
|
|
529
304
|
stationSeparator: this.stationSeparator,
|
|
530
305
|
composite,
|
|
531
306
|
custom: this.customProps,
|
|
532
307
|
};
|
|
533
308
|
return {
|
|
534
|
-
type:
|
|
309
|
+
type: formatTypeToString(this.type),
|
|
535
310
|
precision: this.precision,
|
|
536
311
|
roundFactor: this.roundFactor,
|
|
537
312
|
minWidth: this.minWidth,
|
|
538
|
-
showSignOption:
|
|
539
|
-
formatTraits:
|
|
313
|
+
showSignOption: showSignOptionToString(this.showSignOption),
|
|
314
|
+
formatTraits: formatTraitsToArray(this.formatTraits),
|
|
540
315
|
decimalSeparator: this.decimalSeparator,
|
|
541
316
|
thousandSeparator: this.thousandSeparator,
|
|
542
317
|
uomSeparator: this.uomSeparator,
|
|
543
|
-
scientificType: this.scientificType ?
|
|
318
|
+
scientificType: this.scientificType ? scientificTypeToString(this.scientificType) : undefined,
|
|
544
319
|
stationOffsetSize: this.stationOffsetSize,
|
|
545
320
|
stationSeparator: this.stationSeparator,
|
|
546
321
|
composite,
|