(
marbles: string,
values?: MarbleValueLookup<T>,
error?: unknown,
options: { hot?: boolean } = {}
)
| 48 | } |
| 49 | |
| 50 | export function parseMarbles<T>( |
| 51 | marbles: string, |
| 52 | values?: MarbleValueLookup<T>, |
| 53 | error?: unknown, |
| 54 | options: { hot?: boolean } = {} |
| 55 | ): MarbleMessage<T>[] { |
| 56 | const characters = [...marbles]; |
| 57 | const messages: MarbleMessage<T>[] = []; |
| 58 | let frame = 0; |
| 59 | let groupStart: number | undefined; |
| 60 | let zeroFrame = 0; |
| 61 | let hasZeroMarker = false; |
| 62 | |
| 63 | for (let index = 0; index < characters.length; index++) { |
| 64 | const character = characters[index]; |
| 65 | if (character === undefined) { |
| 66 | break; |
| 67 | } |
| 68 | if (isWhitespace(character)) { |
| 69 | continue; |
| 70 | } |
| 71 | |
| 72 | const duration = readDuration(characters, index); |
| 73 | if (duration) { |
| 74 | frame += duration.milliseconds; |
| 75 | index += duration.length - 1; |
| 76 | continue; |
| 77 | } |
| 78 | |
| 79 | const messageFrame = groupStart ?? frame; |
| 80 | switch (character) { |
| 81 | case '-': |
| 82 | frame += 1; |
| 83 | break; |
| 84 | case '(': |
| 85 | if (groupStart !== undefined) { |
| 86 | throw new Error('Nested marble groups are not supported.'); |
| 87 | } |
| 88 | groupStart = frame; |
| 89 | frame += 1; |
| 90 | break; |
| 91 | case ')': |
| 92 | if (groupStart === undefined) { |
| 93 | throw new Error('Found a closing marble group without an opening group.'); |
| 94 | } |
| 95 | groupStart = undefined; |
| 96 | frame += 1; |
| 97 | break; |
| 98 | case '|': |
| 99 | messages.push({ |
| 100 | frame: messageFrame, |
| 101 | notification: { kind: 'C' }, |
| 102 | }); |
| 103 | frame += 1; |
| 104 | break; |
| 105 | case '#': |
| 106 | messages.push({ |
| 107 | frame: messageFrame, |
no test coverage detected