Skip to content

Commit d75473b

Browse files
committed
Convert Converter to class
1 parent 1dc965d commit d75473b

File tree

2 files changed

+40
-47
lines changed

2 files changed

+40
-47
lines changed

src/tools/text-to-unicode/text-to-unicode.service.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { type ConverterId, SKIP_ASCII_HTML, SKIP_ASCII_JS, converters } from './
33

44
describe('text-to-unicode (legacy tests)', () => {
55
const convertTextToUnicode = (text: string) => converters.decimalEntities.escape(text, false);
6-
const convertUnicodeToText = converters.decimalEntities.unescape;
6+
const convertUnicodeToText = (escaped: string) => converters.decimalEntities.unescape(escaped);
77

88
describe('convertTextToUnicode', () => {
99
it('a text string is converted to unicode representation', () => {

src/tools/text-to-unicode/text-to-unicode.service.ts

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,70 +11,63 @@ function codePoints(text: string): number[] {
1111
return [...text].map(char => char.codePointAt(0));
1212
}
1313

14-
export interface Converter {
14+
interface ConverterConfig {
1515
name: string
16-
escape(text: string, skipAscii: boolean): string
17-
unescape(text: string): string
18-
};
19-
20-
interface EscapeConfig {
21-
charValues?(text: string): number[]
22-
mapper(charValue: number): string
23-
/** @prop regular expression for default content to skip. Must have exactly 1 capture group. */
24-
asciiSkipper: RegExp
25-
};
16+
escape: {
17+
charValues?(text: string): number[]
18+
mapper(charValue: number): string
19+
/** @prop regular expression for default content to skip. Must have exactly 1 capture group. */
20+
asciiSkipper: RegExp
21+
}
22+
unescape: {
23+
regex: RegExp
24+
radix: number
25+
}
26+
}
27+
class Converter {
28+
constructor(public config: ConverterConfig) {}
2629

27-
function escaper({ charValues: getCharValues, mapper, asciiSkipper: skipper }: EscapeConfig) {
28-
return (text: string, skip: boolean): string => {
29-
getCharValues ??= codePoints;
30+
escape(text: string, skipAscii: boolean): string {
31+
const { asciiSkipper, charValues, mapper } = this.config.escape;
32+
const getCharValues = charValues ?? codePoints;
3033

3134
return text
32-
.split(skip ? skipper : SKIP_NOTHING_RE)
33-
.flatMap((x, i) => {
34-
if (i % 2) {
35-
return x;
36-
}
37-
return getCharValues(x).map(mapper);
38-
})
35+
.split(skipAscii ? asciiSkipper : SKIP_NOTHING_RE)
36+
.flatMap((x, i) => i % 2 ? x : getCharValues(x).map(mapper))
3937
.join('');
40-
};
41-
}
38+
}
4239

43-
interface UnescapeConfig {
44-
regex: RegExp
45-
radix: number
46-
};
40+
unescape(escaped: string): string {
41+
const { regex, radix } = this.config.unescape;
4742

48-
function unescaper({ regex, radix }: UnescapeConfig) {
49-
return (escaped: string): string => {
5043
return escaped.replace(regex, (match) => {
5144
return String.fromCodePoint(Number.parseInt(match.replace(/\P{AHex}/gu, ''), radix));
5245
});
53-
};
46+
}
5447
}
5548

5649
export type ConverterId = keyof typeof converters;
5750
const converters = {
58-
fullUnicode: {
51+
fullUnicode: new Converter({
5952
name: 'Full Unicode',
60-
escape: escaper({ mapper: convertCodePointToUnicode, asciiSkipper: SKIP_ASCII_JS }),
61-
unescape: unescaper({ regex: /\\u\p{AHex}{4}|\\u\{\p{AHex}{1,6}\}/gu, radix: 16 }),
62-
},
63-
utf16: {
53+
escape: { mapper: convertCodePointToUnicode, asciiSkipper: SKIP_ASCII_JS },
54+
unescape: { regex: /\\u\p{AHex}{4}|\\u\{\p{AHex}{1,6}\}/gu, radix: 16 },
55+
}),
56+
utf16: new Converter({
6457
name: 'UTF-16 Code Units',
65-
escape: escaper({ charValues: codeUnits, mapper: convertCodePointToUnicode, asciiSkipper: SKIP_ASCII_JS }),
66-
unescape: unescaper({ regex: /\\u\p{AHex}{4}/gu, radix: 16 }),
67-
},
68-
hexEntities: {
58+
escape: { charValues: codeUnits, mapper: convertCodePointToUnicode, asciiSkipper: SKIP_ASCII_JS },
59+
unescape: { regex: /\\u\p{AHex}{4}/gu, radix: 16 },
60+
}),
61+
hexEntities: new Converter({
6962
name: 'HTML Entities (Hex)',
70-
escape: escaper({ mapper: toHexEntities, asciiSkipper: SKIP_ASCII_HTML }),
71-
unescape: unescaper({ regex: /&#x\p{AHex}{1,6};/gu, radix: 16 }),
72-
},
73-
decimalEntities: {
63+
escape: { mapper: toHexEntities, asciiSkipper: SKIP_ASCII_HTML },
64+
unescape: { regex: /&#x\p{AHex}{1,6};/gu, radix: 16 },
65+
}),
66+
decimalEntities: new Converter({
7467
name: 'HTML Entities (Decimal)',
75-
escape: escaper({ mapper: toDecimalEntities, asciiSkipper: SKIP_ASCII_HTML }),
76-
unescape: unescaper({ regex: /&#\d+;/gu, radix: 10 }),
77-
},
68+
escape: { mapper: toDecimalEntities, asciiSkipper: SKIP_ASCII_HTML },
69+
unescape: { regex: /&#\d+;/gu, radix: 10 },
70+
}),
7871
} satisfies Record<string, Converter>;
7972

8073
function convertCodePointToUnicode(codePoint: number): string {

0 commit comments

Comments
 (0)