|
1 | 1 | import { |
2 | 2 | CLOSE_BRACE, |
3 | 3 | CLOSE_BRACKET, |
| 4 | + COMMA, |
4 | 5 | OPEN_BRACE, |
5 | 6 | OPEN_BRACKET, |
| 7 | + OPEN_CALL, |
| 8 | + PIPE, |
6 | 9 | WRONG_KEY, |
7 | 10 | } from './constants'; |
8 | 11 | import { parseKey } from './parser'; |
| 12 | +import { v4 } from 'uuid'; |
| 13 | +import { LexerResult, LexerType } from './types'; |
9 | 14 |
|
10 | | -export const getNVTONType = (str: string) => { |
| 15 | +export const getNVTONType = (str: string): LexerType => { |
11 | 16 | return str.startsWith(OPEN_BRACE) && str.endsWith(CLOSE_BRACE) |
12 | | - ? 'json' |
| 17 | + ? 'object' |
13 | 18 | : str.startsWith(OPEN_BRACKET) && str.endsWith(CLOSE_BRACKET) |
14 | | - ? 'object' |
15 | | - : 'default'; |
| 19 | + ? 'tuple' |
| 20 | + : str.startsWith(OPEN_CALL) |
| 21 | + ? 'function' |
| 22 | + : 'default'; |
16 | 23 | }; |
17 | 24 |
|
18 | 25 | const getCommonTypeCase = (str: string) => { |
19 | 26 | const type = getNVTONType(str); |
20 | 27 |
|
21 | | - if (type === 'default') { |
| 28 | + if (type === 'object' || type === 'default') { |
22 | 29 | return { |
23 | | - data: str, |
24 | | - type, |
25 | | - }; |
26 | | - } |
27 | | - |
28 | | - if (type === 'json') { |
29 | | - return { |
30 | | - data: parseKey(str), |
| 30 | + key: type === 'default' ? str : v4(), |
| 31 | + data: parseKey(str, type), |
31 | 32 | type, |
32 | 33 | }; |
33 | 34 | } |
34 | 35 |
|
35 | 36 | return true; |
36 | 37 | }; |
37 | 38 |
|
38 | | -const normalizeStr = (str: string) => str.substring(1, str.length - 1); |
| 39 | +const normalize = (str: string) => str.substring(1, str.length - 1).trim(); |
39 | 40 |
|
40 | | -// TODO: type |
41 | | -export const lex = (raw: string): any[] => { |
42 | | - return normalizeStr(raw) |
43 | | - .split(/,/g) |
| 41 | +const isTuple = (tuple: string) => |
| 42 | + tuple.startsWith(OPEN_BRACKET) && tuple.endsWith(CLOSE_BRACKET); |
| 43 | + |
| 44 | +export const lex = (raw: string): LexerResult => { |
| 45 | + if (!isTuple(raw)) return []; |
| 46 | + |
| 47 | + return normalize(raw) |
| 48 | + .split(`${COMMA} `) |
44 | 49 | .map((str) => { |
45 | 50 | const def = getCommonTypeCase(str); |
46 | 51 |
|
47 | 52 | if (def !== true) return def; |
48 | 53 |
|
49 | | - const tuples = normalizeStr(str) |
50 | | - .split(/,/g) |
| 54 | + if (!isTuple(str)) return []; |
| 55 | + |
| 56 | + const tuples = normalize(str) |
| 57 | + .split(`${COMMA} `) |
51 | 58 | .map((tuple) => { |
52 | | - const data = normalizeStr(tuple).split('|'); |
| 59 | + const data = normalize(tuple) |
| 60 | + .split(PIPE) |
| 61 | + .map((tg) => tg.trim()) |
| 62 | + .filter(Boolean); |
53 | 63 |
|
54 | | - if (data.length !== 2) return WRONG_KEY; |
| 64 | + if (data.length < 1 || data.length > 2) return WRONG_KEY; |
55 | 65 |
|
56 | | - const [key, value] = data; |
| 66 | + const structure = |
| 67 | + data.length === 1 |
| 68 | + ? { key: data[0], value: data[0] } |
| 69 | + : { key: data[0], value: data[1] }; |
57 | 70 |
|
58 | | - const _def = getCommonTypeCase(value); |
| 71 | + const _def = getCommonTypeCase(structure.value); |
59 | 72 |
|
60 | | - if (_def !== true) |
| 73 | + if (_def !== true) { |
61 | 74 | return { |
62 | | - data: { |
63 | | - key, |
64 | | - value: _def.data, |
65 | | - }, |
| 75 | + key: structure.key, |
| 76 | + data: _def.data, |
66 | 77 | type: _def.type, |
67 | 78 | }; |
| 79 | + } |
| 80 | + |
68 | 81 | // TODO: support recursive tuple format |
69 | | - else return WRONG_KEY; |
| 82 | + return WRONG_KEY; |
70 | 83 | }) |
71 | 84 | .filter((tuple) => tuple !== WRONG_KEY); |
72 | 85 |
|
|
0 commit comments