Skip to content

Commit a67b9a5

Browse files
feat(mf2)!: Drop selection from :currency (unicode-org/message-format-wg#991)
1 parent 9ccd1d5 commit a67b9a5

File tree

4 files changed

+28
-40
lines changed

4 files changed

+28
-40
lines changed

mf2/messageformat/src/functions/currency.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ describe('currencyDisplay', () => {
5656
}
5757
});
5858

59-
test('select=ordinal', () => {
59+
test('selection', () => {
6060
const mf = new MessageFormat(
6161
'en',
62-
'.local $n = {42 :currency currency=EUR select=ordinal} .match $n * {{res}}'
62+
'.local $n = {42 :currency currency=EUR} .match $n 42 {{exact}} * {{other}}'
6363
);
6464
const onError = jest.fn();
65-
expect(mf.format(undefined, onError)).toEqual('res');
66-
expect(onError.mock.calls).toMatchObject([[{ type: 'bad-option' }]]);
65+
expect(mf.format(undefined, onError)).toEqual('other');
66+
expect(onError.mock.calls).toMatchObject([[{ type: 'bad-selector' }]]);
6767
});
6868

6969
describe('complex operand', () => {

mf2/messageformat/src/functions/currency.ts

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import { MessageError, MessageResolutionError } from '../errors.js';
22
import type { MessageFunctionContext } from './index.js';
3-
import {
4-
type MessageNumber,
5-
type MessageNumberOptions,
6-
getMessageNumber,
7-
readNumericOperand
8-
} from './number.js';
3+
import type { MessageNumber, MessageNumberOptions } from './number.js';
4+
import { getMessageNumber, readNumericOperand } from './number.js';
95
import { asPositiveInteger, asString } from './utils.js';
106

117
/**
@@ -74,19 +70,6 @@ export function currency(
7470
}
7571
break;
7672
}
77-
case 'select': {
78-
const strval = asString(optval);
79-
if (strval === 'ordinal') {
80-
throw new MessageResolutionError(
81-
'bad-option',
82-
'Ordinal selection is not supported on :currency',
83-
source
84-
);
85-
}
86-
// @ts-expect-error Let Intl.NumberFormat construction fail
87-
options[name] = strval;
88-
break;
89-
}
9073
}
9174
} catch (error) {
9275
if (error instanceof MessageError) {
@@ -103,5 +86,5 @@ export function currency(
10386
throw new MessageResolutionError('bad-operand', msg, source);
10487
}
10588

106-
return getMessageNumber(ctx, input.value, options);
89+
return getMessageNumber(ctx, input.value, options, false);
10790
}

mf2/messageformat/src/functions/number.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export interface MessageNumber extends MessageValue {
2323
* For example, cardinal English plurals only use `one` and `other`,
2424
* so a key `zero` will never be matched for that locale.
2525
*/
26-
selectKey(keys: Set<string>): string | null;
26+
selectKey?: (keys: Set<string>) => string | null;
2727
toParts?: () => [MessageNumberPart];
2828
toString?: () => string;
2929
valueOf(): number | bigint;
@@ -69,7 +69,8 @@ export function readNumericOperand(
6969
export function getMessageNumber(
7070
{ dir, locales, source }: MessageFunctionContext,
7171
value: number | bigint,
72-
options: MessageNumberOptions
72+
options: MessageNumberOptions,
73+
canSelect: boolean
7374
): MessageNumber {
7475
// @ts-expect-error We may have been a bit naughty earlier.
7576
if (options.useGrouping === 'never') options.useGrouping = false;
@@ -91,17 +92,21 @@ export function getMessageNumber(
9192
get options() {
9293
return { ...options };
9394
},
94-
selectKey(keys) {
95-
const str = String(value);
96-
if (keys.has(str)) return str;
97-
if (options.select === 'exact') return null;
98-
const pluralOpt = options.select
99-
? { ...options, select: undefined, type: options.select }
100-
: options;
101-
// Intl.PluralRules needs a number, not bigint
102-
cat ??= new Intl.PluralRules(locales, pluralOpt).select(Number(value));
103-
return keys.has(cat) ? cat : null;
104-
},
95+
selectKey: canSelect
96+
? keys => {
97+
const str = String(value);
98+
if (keys.has(str)) return str;
99+
if (options.select === 'exact') return null;
100+
const pluralOpt = options.select
101+
? { ...options, select: undefined, type: options.select }
102+
: options;
103+
// Intl.PluralRules needs a number, not bigint
104+
cat ??= new Intl.PluralRules(locales, pluralOpt).select(
105+
Number(value)
106+
);
107+
return keys.has(cat) ? cat : null;
108+
}
109+
: undefined,
105110
toParts() {
106111
nf ??= new Intl.NumberFormat(locales, options);
107112
const parts = nf.formatToParts(value);
@@ -169,7 +174,7 @@ export function number(
169174
}
170175
}
171176

172-
return getMessageNumber(ctx, value, options);
177+
return getMessageNumber(ctx, value, options, true);
173178
}
174179

175180
/**
@@ -218,5 +223,5 @@ export function integer(
218223
}
219224
}
220225

221-
return getMessageNumber(ctx, value, options);
226+
return getMessageNumber(ctx, value, options, true);
222227
}

0 commit comments

Comments
 (0)