@futpib/parser 1.0.1 → 1.0.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/.github/copilot-instructions.md +149 -0
- package/.github/workflows/copilot-setup-steps.yml +18 -0
- package/.github/workflows/main.yml +29 -8
- package/.yarn/releases/yarn-4.9.4.cjs +942 -0
- package/.yarnrc.yml +1 -1
- package/build/allSettledStream.js +32 -14
- package/build/allSettledStream.test.js +32 -0
- package/build/androidPackage.d.ts +39 -0
- package/build/androidPackageParser.d.ts +17 -0
- package/build/androidPackageParser.js +185 -0
- package/build/androidPackageParser.test.js +22 -0
- package/build/androidPackageUnparser.d.ts +4 -0
- package/build/androidPackageUnparser.js +94 -0
- package/build/androidPackageUnparser.test.js +26 -0
- package/build/arbitrarilySlicedAsyncInterable.d.ts +3 -1
- package/build/arbitrarilySlicedAsyncInterable.js +3 -3
- package/build/arbitrarilySlicedAsyncInterator.js +2 -1
- package/build/arbitraryDalvikBytecode.d.ts +4 -0
- package/build/arbitraryDalvikBytecode.js +640 -0
- package/build/arbitraryDalvikExecutable.d.ts +3 -0
- package/build/arbitraryDalvikExecutable.js +282 -0
- package/build/arbitraryDosDateTime.js +1 -0
- package/build/arbitraryZipStream.js +1 -1
- package/build/arrayParser.js +2 -2
- package/build/arrayParser.test.js +3 -3
- package/build/arrayUnparser.d.ts +1 -1
- package/build/backsmali.d.ts +3 -0
- package/build/backsmali.js +50 -0
- package/build/bsonParser.js +6 -2
- package/build/customInvariant.d.ts +2 -1
- package/build/customInvariant.js +4 -6
- package/build/dalvikBytecodeParser/formatParsers.d.ts +171 -0
- package/build/dalvikBytecodeParser/formatParsers.js +304 -0
- package/build/dalvikBytecodeParser/formatSizes.d.ts +34 -0
- package/build/dalvikBytecodeParser/formatSizes.js +34 -0
- package/build/dalvikBytecodeParser/operationFormats.d.ts +225 -0
- package/build/dalvikBytecodeParser/operationFormats.js +225 -0
- package/build/dalvikBytecodeParser.d.ts +1207 -0
- package/build/dalvikBytecodeParser.js +1289 -0
- package/build/dalvikBytecodeUnparser/formatUnparsers.d.ts +152 -0
- package/build/dalvikBytecodeUnparser/formatUnparsers.js +225 -0
- package/build/dalvikBytecodeUnparser.d.ts +3 -0
- package/build/dalvikBytecodeUnparser.js +642 -0
- package/build/dalvikBytecodeUnparser.test.js +25 -0
- package/build/dalvikExecutable.d.ts +215 -0
- package/build/dalvikExecutable.js +56 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.d.ts +4 -0
- package/build/dalvikExecutableParser/stringSyntaxParser.js +76 -0
- package/build/dalvikExecutableParser/typeParsers.d.ts +11 -0
- package/build/dalvikExecutableParser/typeParsers.js +39 -0
- package/build/dalvikExecutableParser/typedNumbers.d.ts +106 -0
- package/build/dalvikExecutableParser/typedNumbers.js +18 -0
- package/build/dalvikExecutableParser.d.ts +5 -0
- package/build/dalvikExecutableParser.js +1757 -0
- package/build/dalvikExecutableParser.test.js +72 -0
- package/build/dalvikExecutableParserAgainstSmaliParser.test.js +275 -0
- package/build/dalvikExecutableUnparser/annotationUnparsers.d.ts +14 -0
- package/build/dalvikExecutableUnparser/annotationUnparsers.js +97 -0
- package/build/dalvikExecutableUnparser/poolBuilders.d.ts +49 -0
- package/build/dalvikExecutableUnparser/poolBuilders.js +140 -0
- package/build/dalvikExecutableUnparser/poolScanners.d.ts +4 -0
- package/build/dalvikExecutableUnparser/poolScanners.js +220 -0
- package/build/dalvikExecutableUnparser/sectionUnparsers.d.ts +25 -0
- package/build/dalvikExecutableUnparser/sectionUnparsers.js +581 -0
- package/build/dalvikExecutableUnparser/utils.d.ts +10 -0
- package/build/dalvikExecutableUnparser/utils.js +108 -0
- package/build/dalvikExecutableUnparser.d.ts +4 -0
- package/build/dalvikExecutableUnparser.js +406 -0
- package/build/dalvikExecutableUnparser.test.js +31 -0
- package/build/debugLogInputParser.d.ts +4 -0
- package/build/debugLogInputParser.js +16 -0
- package/build/debugLogParser.js +14 -3
- package/build/disjunctionParser.d.ts +2 -1
- package/build/disjunctionParser.js +6 -4
- package/build/elementTerminatedArrayParser.d.ts +3 -0
- package/build/elementTerminatedArrayParser.js +18 -0
- package/build/elementTerminatedArrayParser.test.js +52 -0
- package/build/elementTerminatedSequenceArrayParser.d.ts +3 -0
- package/build/elementTerminatedSequenceArrayParser.js +32 -0
- package/build/elementTerminatedSequenceArrayParser.test.js +34 -0
- package/build/elementTerminatedSequenceParser.d.ts +3 -0
- package/build/elementTerminatedSequenceParser.js +27 -0
- package/build/elementTerminatedSequenceParser.test.js +34 -0
- package/build/endOfInputParser.d.ts +1 -1
- package/build/exactElementParser.js +10 -5
- package/build/exactElementSwitchParser.d.ts +3 -0
- package/build/exactElementSwitchParser.js +22 -0
- package/build/exactSequenceParser.d.ts +2 -1
- package/build/exactSequenceParser.js +12 -2
- package/build/fetchCid.d.ts +1 -0
- package/build/fetchCid.js +103 -0
- package/build/fetchCid.test.js +16 -0
- package/build/fixedLengthSequenceParser.d.ts +1 -0
- package/build/fixedLengthSequenceParser.js +18 -1
- package/build/fixedLengthSequenceParser.test.js +41 -0
- package/build/hasExecutable.d.ts +1 -0
- package/build/hasExecutable.js +8 -0
- package/build/highResolutionTimer.d.ts +16 -0
- package/build/highResolutionTimer.js +42 -0
- package/build/inputReader.d.ts +11 -0
- package/build/inputReader.js +37 -0
- package/build/inputReader.test.js +161 -8
- package/build/inputReaderState.d.ts +10 -0
- package/build/inputReaderState.js +16 -0
- package/build/inspect.d.ts +1 -0
- package/build/inspect.js +7 -0
- package/build/javaKeyStoreParser.test.js +8 -8
- package/build/jsonParser.d.ts +2 -0
- package/build/jsonParser.js +19 -22
- package/build/lazyMessageError.d.ts +48 -0
- package/build/lazyMessageError.js +53 -0
- package/build/lazyMessageError.test.d.ts +1 -0
- package/build/lazyMessageError.test.js +15 -0
- package/build/leb128Parser.d.ts +7 -0
- package/build/leb128Parser.js +82 -0
- package/build/leb128Parser.test.d.ts +1 -0
- package/build/leb128Parser.test.js +107 -0
- package/build/lookaheadParser.d.ts +2 -0
- package/build/lookaheadParser.js +14 -0
- package/build/negativeLookaheadParser.js +22 -16
- package/build/negativeLookaheadParser.test.d.ts +1 -0
- package/build/negativeLookaheadParser.test.js +30 -0
- package/build/noStackCaptureOverheadError.d.ts +4 -0
- package/build/noStackCaptureOverheadError.js +9 -0
- package/build/noStackCaptureOverheadError.test.d.ts +1 -0
- package/build/noStackCaptureOverheadError.test.js +15 -0
- package/build/nonEmptyArrayParser.d.ts +2 -0
- package/build/nonEmptyArrayParser.js +32 -0
- package/build/nonEmptyArrayParser.test.d.ts +1 -0
- package/build/nonEmptyArrayParser.test.js +17 -0
- package/build/optionalParser.js +2 -2
- package/build/parser.d.ts +11 -1
- package/build/parser.js +82 -32
- package/build/parser.test.js +141 -25
- package/build/parserAccessorParser.js +9 -1
- package/build/parserConsumedSequenceParser.d.ts +1 -1
- package/build/parserConsumedSequenceParser.js +21 -16
- package/build/parserContext.d.ts +22 -6
- package/build/parserContext.js +113 -57
- package/build/parserContext.test.js +33 -2
- package/build/parserCreatorCompose.d.ts +1 -0
- package/build/parserCreatorCompose.js +8 -2
- package/build/parserError.d.ts +605 -40
- package/build/parserError.js +98 -53
- package/build/parserImplementationInvariant.d.ts +1 -1
- package/build/parserImplementationInvariant.js +2 -2
- package/build/parserInputCompanion.d.ts +15 -0
- package/build/parserInputCompanion.js +38 -0
- package/build/promiseCompose.d.ts +1 -1
- package/build/promiseCompose.js +11 -1
- package/build/promiseSettled.d.ts +1 -0
- package/build/promiseSettled.js +4 -0
- package/build/separatedArrayParser.d.ts +2 -0
- package/build/separatedArrayParser.js +39 -0
- package/build/separatedArrayParser.test.d.ts +1 -0
- package/build/separatedArrayParser.test.js +21 -0
- package/build/separatedNonEmptyArrayParser.d.ts +2 -0
- package/build/separatedNonEmptyArrayParser.js +40 -0
- package/build/separatedNonEmptyArrayParser.test.d.ts +1 -0
- package/build/separatedNonEmptyArrayParser.test.js +66 -0
- package/build/sequenceBuffer.d.ts +10 -0
- package/build/sequenceBuffer.js +54 -2
- package/build/sequenceBuffer.test.js +57 -0
- package/build/sequenceTerminatedSequenceParser.d.ts +5 -0
- package/build/sequenceTerminatedSequenceParser.js +32 -0
- package/build/sequenceTerminatedSequenceParser.test.d.ts +1 -0
- package/build/sequenceTerminatedSequenceParser.test.js +37 -0
- package/build/sequenceUnparser.d.ts +1 -1
- package/build/skipParser.d.ts +1 -1
- package/build/skipParser.js +4 -2
- package/build/skipToParser.d.ts +2 -0
- package/build/skipToParser.js +11 -0
- package/build/sliceBoundedParser.d.ts +1 -1
- package/build/sliceBoundedParser.js +7 -2
- package/build/sliceBoundedParser.test.js +30 -1
- package/build/smali.d.ts +1 -0
- package/build/smali.js +21 -0
- package/build/smaliParser.d.ts +68 -0
- package/build/smaliParser.js +2081 -0
- package/build/smaliParser.test.d.ts +1 -0
- package/build/smaliParser.test.js +410 -0
- package/build/stringFromAsyncIterable.d.ts +1 -0
- package/build/stringFromAsyncIterable.js +7 -0
- package/build/terminatedArrayParser.d.ts +3 -1
- package/build/terminatedArrayParser.js +79 -2
- package/build/terminatedArrayParser.test.d.ts +1 -0
- package/build/terminatedArrayParser.test.js +131 -0
- package/build/toAsyncIterable.d.ts +1 -0
- package/build/toAsyncIterable.js +7 -0
- package/build/toAsyncIterator.d.ts +1 -0
- package/build/toAsyncIterator.js +33 -0
- package/build/tupleParser.d.ts +4 -0
- package/build/tupleParser.js +1 -5
- package/build/unionParser.d.ts +2 -1
- package/build/unionParser.js +29 -14
- package/build/unionParser.test.d.ts +1 -0
- package/build/unionParser.test.js +60 -0
- package/build/unparser.d.ts +3 -3
- package/build/unparser.js +6 -4
- package/build/unparser.test.js +7 -19
- package/build/unparserContext.d.ts +2 -2
- package/build/unparserContext.js +2 -3
- package/build/unparserError.d.ts +2 -1
- package/build/unparserError.js +2 -1
- package/build/unparserImplementationInvariant.d.ts +1 -1
- package/build/unparserOutputCompanion.d.ts +1 -1
- package/build/unparserOutputCompanion.js +1 -1
- package/build/zipParser.d.ts +7 -2
- package/build/zipParser.js +36 -12
- package/build/zipUnparser.d.ts +7 -4
- package/build/zipUnparser.js +64 -45
- package/build/zipUnparser.test.js +15 -15
- package/package.json +33 -24
- package/src/allSettledStream.test.ts +40 -0
- package/src/allSettledStream.ts +47 -15
- package/src/androidPackage.ts +48 -0
- package/src/androidPackageParser.test.ts +27 -0
- package/src/{apkParser.test.ts.md → androidPackageParser.test.ts.md} +4 -4
- package/src/androidPackageParser.test.ts.snap +0 -0
- package/src/androidPackageParser.ts +398 -0
- package/src/androidPackageUnparser.test.ts +34 -0
- package/src/androidPackageUnparser.ts +126 -0
- package/src/arbitrarilySlicedAsyncInterable.ts +7 -2
- package/src/arbitrarilySlicedAsyncInterator.ts +4 -4
- package/src/arbitraryDalvikBytecode.ts +992 -0
- package/src/arbitraryDalvikExecutable.ts +434 -0
- package/src/arbitraryDosDateTime.ts +1 -0
- package/src/arbitraryZipStream.ts +1 -1
- package/src/arrayParser.test.ts +3 -3
- package/src/arrayParser.ts +2 -2
- package/src/arrayUnparser.ts +2 -2
- package/src/backsmali.ts +74 -0
- package/src/bsonParser.test.ts +12 -14
- package/src/bsonParser.ts +13 -2
- package/src/customInvariant.ts +8 -12
- package/src/dalvikBytecodeParser/formatParsers.ts +780 -0
- package/src/dalvikBytecodeParser/formatSizes.ts +35 -0
- package/src/dalvikBytecodeParser/operationFormats.ts +226 -0
- package/src/dalvikBytecodeParser.ts +2873 -0
- package/src/dalvikBytecodeUnparser/formatUnparsers.ts +442 -0
- package/src/dalvikBytecodeUnparser.test.ts +44 -0
- package/src/dalvikBytecodeUnparser.ts +758 -0
- package/src/dalvikExecutable.ts +282 -0
- package/src/dalvikExecutableParser/stringSyntaxParser.ts +145 -0
- package/src/dalvikExecutableParser/typeParsers.ts +74 -0
- package/src/dalvikExecutableParser/typedNumbers.ts +57 -0
- package/src/dalvikExecutableParser.test.ts +89 -0
- package/src/dalvikExecutableParser.test.ts.md +634 -0
- package/src/dalvikExecutableParser.test.ts.snap +0 -0
- package/src/dalvikExecutableParser.ts +3245 -0
- package/src/dalvikExecutableParserAgainstSmaliParser.test.ts +363 -0
- package/src/dalvikExecutableUnparser/annotationUnparsers.ts +135 -0
- package/src/dalvikExecutableUnparser/poolBuilders.ts +189 -0
- package/src/dalvikExecutableUnparser/poolScanners.ts +297 -0
- package/src/dalvikExecutableUnparser/sectionUnparsers.ts +683 -0
- package/src/dalvikExecutableUnparser/utils.ts +149 -0
- package/src/dalvikExecutableUnparser.test.ts +57 -0
- package/src/dalvikExecutableUnparser.ts +581 -0
- package/src/debugLogInputParser.ts +28 -0
- package/src/debugLogParser.ts +19 -3
- package/src/disjunctionParser.ts +12 -7
- package/src/elementTerminatedArrayParser.test.ts +99 -0
- package/src/elementTerminatedArrayParser.ts +31 -0
- package/src/elementTerminatedSequenceArrayParser.test.ts +52 -0
- package/src/elementTerminatedSequenceArrayParser.ts +52 -0
- package/src/elementTerminatedSequenceParser.test.ts +52 -0
- package/src/elementTerminatedSequenceParser.ts +43 -0
- package/src/endOfInputParser.ts +1 -1
- package/src/exactElementParser.ts +17 -11
- package/src/exactElementSwitchParser.ts +41 -0
- package/src/exactSequenceParser.ts +23 -2
- package/src/fetchCid.test.ts +20 -0
- package/src/fetchCid.ts +121 -0
- package/src/fixedLengthSequenceParser.test.ts +75 -0
- package/src/fixedLengthSequenceParser.ts +28 -1
- package/src/hasExecutable.ts +11 -0
- package/src/highResolutionTimer.ts +49 -0
- package/src/inputReader.test.ts +204 -8
- package/src/inputReader.ts +76 -3
- package/src/inputReaderState.ts +33 -0
- package/src/inspect.ts +9 -0
- package/src/javaKeyStoreParser.test.ts +12 -15
- package/src/javaKeyStoreParser.ts +2 -6
- package/src/jsonParser.test.ts +2 -4
- package/src/jsonParser.ts +46 -62
- package/src/lazyMessageError.test.ts +21 -0
- package/src/lazyMessageError.ts +88 -0
- package/src/leb128Parser.test.ts +173 -0
- package/src/leb128Parser.ts +125 -0
- package/src/lookaheadParser.ts +19 -0
- package/src/negativeLookaheadParser.test.ts +49 -0
- package/src/negativeLookaheadParser.ts +27 -15
- package/src/noStackCaptureOverheadError.test.ts +17 -0
- package/src/noStackCaptureOverheadError.ts +12 -0
- package/src/nonEmptyArrayParser.test.ts +21 -0
- package/src/nonEmptyArrayParser.ts +44 -0
- package/src/optionalParser.ts +3 -2
- package/src/parser.test.ts +203 -31
- package/src/parser.test.ts.md +34 -27
- package/src/parser.test.ts.snap +0 -0
- package/src/parser.ts +172 -45
- package/src/parserAccessorParser.ts +12 -2
- package/src/parserConsumedSequenceParser.ts +26 -17
- package/src/parserContext.test.ts +37 -2
- package/src/parserContext.ts +185 -79
- package/src/parserCreatorCompose.ts +20 -2
- package/src/parserError.ts +144 -61
- package/src/parserImplementationInvariant.ts +3 -3
- package/src/parserInputCompanion.ts +55 -0
- package/src/promiseCompose.ts +17 -3
- package/src/promiseSettled.ts +6 -0
- package/src/separatedArrayParser.test.ts +34 -0
- package/src/separatedArrayParser.ts +55 -0
- package/src/separatedNonEmptyArrayParser.test.ts +117 -0
- package/src/separatedNonEmptyArrayParser.ts +61 -0
- package/src/sequenceBuffer.test.ts +70 -0
- package/src/sequenceBuffer.ts +88 -2
- package/src/sequenceTerminatedSequenceParser.test.ts +58 -0
- package/src/sequenceTerminatedSequenceParser.ts +62 -0
- package/src/sequenceUnparser.ts +2 -2
- package/src/skipParser.ts +7 -5
- package/src/skipToParser.ts +16 -0
- package/src/sliceBoundedParser.test.ts +35 -1
- package/src/sliceBoundedParser.ts +19 -1
- package/src/smali.ts +29 -0
- package/src/smaliParser.test.ts +443 -0
- package/src/smaliParser.test.ts.md +3907 -0
- package/src/smaliParser.test.ts.snap +0 -0
- package/src/smaliParser.ts +3348 -0
- package/src/stringFromAsyncIterable.ts +9 -0
- package/src/terminatedArrayParser.test.ts +258 -0
- package/src/terminatedArrayParser.ts +109 -6
- package/src/toAsyncIterable.ts +7 -0
- package/src/toAsyncIterator.ts +48 -0
- package/src/tupleParser.ts +8 -5
- package/src/uint8Array.ts +2 -3
- package/src/unionParser.test.ts +78 -0
- package/src/unionParser.ts +47 -21
- package/src/unparser.test.ts +18 -34
- package/src/unparser.ts +13 -9
- package/src/unparserContext.ts +9 -13
- package/src/unparserError.ts +2 -1
- package/src/unparserImplementationInvariant.ts +1 -1
- package/src/unparserOutputCompanion.ts +1 -1
- package/src/zip.ts +2 -6
- package/src/zipParser.ts +71 -20
- package/src/zipUnparser.test.ts +19 -19
- package/src/zipUnparser.ts +139 -90
- package/tsconfig.json +7 -1
- package/xo.config.ts +15 -0
- package/.yarn/releases/yarn-4.5.3.cjs +0 -934
- package/build/apk.d.ts +0 -39
- package/build/apkParser.d.ts +0 -16
- package/build/apkParser.js +0 -164
- package/build/apkParser.test.js +0 -22
- package/build/apkUnparser.d.ts +0 -4
- package/build/apkUnparser.js +0 -90
- package/build/apkUnparser.test.js +0 -26
- package/build/arbitraryDosDate.d.ts +0 -2
- package/build/arbitraryDosDate.js +0 -8
- package/build/arbitraryZipEntry.d.ts +0 -3
- package/build/arbitraryZipEntry.js +0 -26
- package/build/createDisjunctionParser.d.ts +0 -2
- package/build/createDisjunctionParser.js +0 -47
- package/build/createExactParser.d.ts +0 -2
- package/build/createExactParser.js +0 -12
- package/build/createSequentialUnionParser.d.ts +0 -2
- package/build/createSequentialUnionParser.js +0 -69
- package/build/fixedLengthChunkParser.d.ts +0 -2
- package/build/fixedLengthChunkParser.js +0 -12
- package/build/fixedLengthParser.d.ts +0 -2
- package/build/fixedLengthParser.js +0 -12
- package/build/inputChunkBuffer.d.ts +0 -15
- package/build/inputChunkBuffer.js +0 -40
- package/build/inputChunkBuffer.test.js +0 -34
- package/build/inputCompanion.d.ts +0 -18
- package/build/inputCompanion.js +0 -28
- package/build/invariantDefined.d.ts +0 -1
- package/build/invariantDefined.js +0 -5
- package/build/invariantIdentity.d.ts +0 -3
- package/build/invariantIdentity.js +0 -5
- package/build/javaKeystoreParser.d.ts +0 -2
- package/build/javaKeystoreParser.js +0 -7
- package/build/jsonParser2.d.ts +0 -3
- package/build/jsonParser2.js +0 -52
- package/build/jsonParser2.test.js +0 -22
- package/build/negativeLookahead.d.ts +0 -2
- package/build/negativeLookahead.js +0 -18
- package/build/parserCompose.d.ts +0 -3
- package/build/parserCompose.js +0 -7
- package/build/parserImplementationInvariantInvariant.d.ts +0 -3
- package/build/parserImplementationInvariantInvariant.js +0 -15
- package/build/parserInvariant.d.ts +0 -4
- package/build/parserInvariant.js +0 -11
- package/build/promiseFish.d.ts +0 -1
- package/build/promiseFish.js +0 -3
- package/build/sequenceParser.d.ts +0 -3
- package/build/sequenceParser.js +0 -10
- package/build/terminatedSequenceParser.d.ts +0 -2
- package/build/terminatedSequenceParser.js +0 -24
- package/build/unparserInputCompanion.d.ts +0 -15
- package/build/unparserInputCompanion.js +0 -13
- package/build/zipEntry.d.ts +0 -28
- package/build/zipFile.d.ts +0 -32
- package/build/zipFileEntry.d.ts +0 -6
- package/src/apk.ts +0 -48
- package/src/apkParser.test.ts +0 -30
- package/src/apkParser.test.ts.snap +0 -0
- package/src/apkParser.ts +0 -392
- package/src/apkUnparser.test.ts +0 -37
- package/src/apkUnparser.ts +0 -120
- package/src/invariantDefined.ts +0 -6
- package/src/invariantIdentity.ts +0 -8
- /package/build/{apk.js → androidPackage.js} +0 -0
- /package/build/{apkParser.test.d.ts → androidPackageParser.test.d.ts} +0 -0
- /package/build/{apkUnparser.test.d.ts → androidPackageUnparser.test.d.ts} +0 -0
- /package/build/{arbitraryDosPermissions.d.ts → dalvikBytecodeUnparser.test.d.ts} +0 -0
- /package/build/{arbitraryDosPermissions.js → dalvikExecutableParser.test.d.ts} +0 -0
- /package/build/{inputChunkBuffer.test.d.ts → dalvikExecutableParserAgainstSmaliParser.test.d.ts} +0 -0
- /package/build/{jsonParser2.test.d.ts → dalvikExecutableUnparser.test.d.ts} +0 -0
- /package/build/{parserParsingInvariant.d.ts → elementTerminatedArrayParser.test.d.ts} +0 -0
- /package/build/{parserParsingInvariant.js → elementTerminatedSequenceArrayParser.test.d.ts} +0 -0
- /package/build/{zipEntry.js → elementTerminatedSequenceParser.test.d.ts} +0 -0
- /package/build/{zipFile.js → fetchCid.test.d.ts} +0 -0
- /package/build/{zipFileEntry.js → fixedLengthSequenceParser.test.d.ts} +0 -0
package/src/parserError.ts
CHANGED
|
@@ -1,85 +1,168 @@
|
|
|
1
|
+
import { type InputReaderState } from './inputReaderState.js';
|
|
2
|
+
import { LazyMessage, NormalLazyMessageError, NoStackCaptureOverheadLazyMessageError } from './lazyMessageError.js';
|
|
1
3
|
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
+
export interface ParserError extends Error {
|
|
5
|
+
position: undefined | number;
|
|
6
|
+
inputReaderSate: undefined | InputReaderState<unknown>;
|
|
4
7
|
}
|
|
5
8
|
|
|
6
|
-
export
|
|
7
|
-
|
|
9
|
+
export function isParserError(value: unknown): value is ParserError {
|
|
10
|
+
return (
|
|
11
|
+
typeof value === 'object'
|
|
12
|
+
&& value !== null
|
|
13
|
+
&& value instanceof Error
|
|
14
|
+
&& 'position' in value
|
|
15
|
+
&& (typeof value.position === 'number' || value.position === undefined)
|
|
16
|
+
&& 'inputReaderSate' in value
|
|
17
|
+
&& (value.inputReaderSate === undefined || typeof value.inputReaderSate === 'object')
|
|
18
|
+
);
|
|
8
19
|
}
|
|
9
|
-
|
|
10
|
-
|
|
20
|
+
|
|
21
|
+
type ParserErrorInterface = ParserError;
|
|
22
|
+
|
|
23
|
+
export interface ParserParsingFailedError extends ParserErrorInterface {
|
|
24
|
+
depth: number;
|
|
25
|
+
position: number;
|
|
11
26
|
}
|
|
12
27
|
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
position,
|
|
24
|
-
') ',
|
|
25
|
-
message,
|
|
26
|
-
].join(''));
|
|
27
|
-
}
|
|
28
|
+
export function isParserParsingFailedError(value: unknown): value is ParserParsingFailedError {
|
|
29
|
+
return (
|
|
30
|
+
typeof value === 'object'
|
|
31
|
+
&& value !== null
|
|
32
|
+
&& value instanceof Error
|
|
33
|
+
&& 'depth' in value
|
|
34
|
+
&& typeof value.depth === 'number'
|
|
35
|
+
&& 'position' in value
|
|
36
|
+
&& typeof value.position === 'number'
|
|
37
|
+
);
|
|
28
38
|
}
|
|
29
39
|
|
|
30
|
-
|
|
31
|
-
name = 'ParserParsingJoinError';
|
|
40
|
+
type ParserParsingFailedErrorInterface = ParserParsingFailedError;
|
|
32
41
|
|
|
33
|
-
|
|
42
|
+
export interface ParserParsingJoinError extends ParserParsingFailedErrorInterface {
|
|
43
|
+
childErrors: ParserParsingFailedErrorInterface[];
|
|
34
44
|
}
|
|
35
45
|
|
|
36
|
-
export
|
|
37
|
-
|
|
46
|
+
export function isParserParsingJoinError(value: unknown): value is ParserParsingJoinError {
|
|
47
|
+
return (
|
|
48
|
+
typeof value === 'object'
|
|
49
|
+
&& value !== null
|
|
50
|
+
&& value instanceof Error
|
|
51
|
+
&& 'childErrors' in value
|
|
52
|
+
&& Array.isArray(value.childErrors)
|
|
53
|
+
&& value.childErrors.every((childError: unknown) => isParserParsingFailedError(childError))
|
|
54
|
+
);
|
|
38
55
|
}
|
|
39
56
|
|
|
40
|
-
|
|
41
|
-
|
|
57
|
+
type ParserParsingJoinErrorInterface = ParserParsingJoinError;
|
|
58
|
+
|
|
59
|
+
function createParserErrorModule(
|
|
60
|
+
BaseLazyMessageError: typeof NormalLazyMessageError | typeof NoStackCaptureOverheadLazyMessageError,
|
|
61
|
+
) {
|
|
62
|
+
class ParserError extends BaseLazyMessageError implements ParserErrorInterface {
|
|
63
|
+
name = 'ParserError';
|
|
42
64
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
65
|
+
public position: undefined | number = undefined;
|
|
66
|
+
public inputReaderSate: undefined | InputReaderState<unknown> = undefined;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
class ParserImplementationError extends ParserError {
|
|
70
|
+
name = 'ParserImplementationError';
|
|
71
|
+
}
|
|
72
|
+
class ParserImplementationInvariantError extends ParserImplementationError {
|
|
73
|
+
name = 'ParserImplementationInvariantError';
|
|
50
74
|
}
|
|
51
|
-
}
|
|
52
75
|
|
|
53
|
-
|
|
54
|
-
|
|
76
|
+
class ParserParsingFailedError extends ParserError implements ParserParsingFailedErrorInterface {
|
|
77
|
+
name = 'ParserParsingFailedError';
|
|
55
78
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
79
|
+
constructor(
|
|
80
|
+
message: LazyMessage,
|
|
81
|
+
public readonly depth: number,
|
|
82
|
+
public readonly position: number,
|
|
83
|
+
) {
|
|
84
|
+
super(message);
|
|
85
|
+
}
|
|
63
86
|
}
|
|
64
|
-
}
|
|
65
87
|
|
|
66
|
-
|
|
67
|
-
|
|
88
|
+
class ParserParsingJoinError extends ParserParsingFailedError implements ParserParsingJoinErrorInterface {
|
|
89
|
+
name = 'ParserParsingJoinError';
|
|
68
90
|
|
|
69
|
-
|
|
70
|
-
message: string,
|
|
71
|
-
depth: number,
|
|
72
|
-
position: number,
|
|
73
|
-
public readonly childErrors: ParserParsingFailedError[],
|
|
74
|
-
) {
|
|
75
|
-
super(message, depth, position);
|
|
91
|
+
public readonly childErrors: ParserParsingFailedErrorInterface[] = [];
|
|
76
92
|
}
|
|
77
|
-
}
|
|
78
93
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
94
|
+
class ParserParsingJoinNoneError extends ParserParsingJoinError {
|
|
95
|
+
name = 'ParserParsingJoinNoneError';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
class ParserParsingJoinAllError extends ParserParsingJoinError {
|
|
99
|
+
name = 'ParserParsingJoinAllError';
|
|
100
|
+
|
|
101
|
+
constructor(
|
|
102
|
+
message: LazyMessage,
|
|
103
|
+
depth: number,
|
|
104
|
+
position: number,
|
|
105
|
+
public readonly childErrors: ParserParsingFailedErrorInterface[],
|
|
106
|
+
) {
|
|
107
|
+
super(message, depth, position);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
82
110
|
|
|
83
|
-
|
|
84
|
-
|
|
111
|
+
class ParserParsingJoinDeepestError extends ParserParsingJoinError {
|
|
112
|
+
name = 'ParserParsingJoinDeepestError';
|
|
113
|
+
|
|
114
|
+
constructor(
|
|
115
|
+
message: LazyMessage,
|
|
116
|
+
depth: number,
|
|
117
|
+
position: number,
|
|
118
|
+
public readonly childErrors: ParserParsingFailedErrorInterface[],
|
|
119
|
+
) {
|
|
120
|
+
super(message, depth, position);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
class ParserParsingJoinFurthestError extends ParserParsingJoinError {
|
|
125
|
+
name = 'ParserParsingJoinFurthestError';
|
|
126
|
+
|
|
127
|
+
constructor(
|
|
128
|
+
message: LazyMessage,
|
|
129
|
+
depth: number,
|
|
130
|
+
position: number,
|
|
131
|
+
public readonly childErrors: ParserParsingFailedErrorInterface[],
|
|
132
|
+
) {
|
|
133
|
+
super(message, depth, position);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
class ParserParsingInvariantError extends ParserParsingFailedError {
|
|
138
|
+
name = 'ParserParsingInvariantError';
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
class ParserUnexpectedEndOfInputError extends ParserParsingFailedError {
|
|
142
|
+
name = 'ParserUnexpectedEndOfInputError';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
class ParserUnexpectedRemainingInputError extends ParserParsingFailedError {
|
|
146
|
+
name = 'ParserUnexpectedRemainingInputError';
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
ParserError,
|
|
151
|
+
ParserImplementationError,
|
|
152
|
+
ParserImplementationInvariantError,
|
|
153
|
+
ParserParsingFailedError,
|
|
154
|
+
ParserParsingJoinError,
|
|
155
|
+
ParserParsingJoinNoneError,
|
|
156
|
+
ParserParsingJoinAllError,
|
|
157
|
+
ParserParsingJoinDeepestError,
|
|
158
|
+
ParserParsingJoinFurthestError,
|
|
159
|
+
ParserParsingInvariantError,
|
|
160
|
+
ParserUnexpectedEndOfInputError,
|
|
161
|
+
ParserUnexpectedRemainingInputError,
|
|
162
|
+
};
|
|
85
163
|
}
|
|
164
|
+
|
|
165
|
+
export type ParserErrorModule = ReturnType<typeof createParserErrorModule>;
|
|
166
|
+
|
|
167
|
+
export const normalParserErrorModule = createParserErrorModule(NormalLazyMessageError);
|
|
168
|
+
export const noStackCaptureOverheadParserErrorModule = createParserErrorModule(NoStackCaptureOverheadLazyMessageError);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ParserImplementationInvariantError } from './parserError.js';
|
|
2
1
|
import { type Falsy, customInvariant, type ValueOrAccessor } from './customInvariant.js';
|
|
2
|
+
import { normalParserErrorModule } from './parserError.js';
|
|
3
3
|
|
|
4
|
-
export function parserImplementationInvariant<T>(value: T, format: ValueOrAccessor<string | string[]>, ...formatArguments:
|
|
5
|
-
return customInvariant(ParserImplementationInvariantError, value, format, ...formatArguments);
|
|
4
|
+
export function parserImplementationInvariant<T>(value: T, format: ValueOrAccessor<string | string[]>, ...formatArguments: unknown[]): Exclude<T, Falsy> {
|
|
5
|
+
return customInvariant(normalParserErrorModule.ParserImplementationInvariantError, value, format, ...formatArguments);
|
|
6
6
|
}
|
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
export type ParserInputCompanion<Sequence, Element> = {
|
|
3
3
|
is(value: unknown): value is Sequence;
|
|
4
4
|
from(elements: Element[]): Sequence;
|
|
5
|
+
concat(sequences: Sequence[]): Sequence;
|
|
5
6
|
length(sequence: Sequence): number;
|
|
6
7
|
at(sequence: Sequence, index: number): Element | undefined;
|
|
8
|
+
subsequence(sequence: Sequence, start: number, end: number): Sequence;
|
|
9
|
+
indexOf(sequence: Sequence, element: Element, fromIndex?: number): number;
|
|
10
|
+
indexOfSubsequence(sequence: Sequence, subsequence: Sequence, fromIndex?: number): number;
|
|
11
|
+
equals(sequenceA: Sequence, sequenceB: Sequence): boolean;
|
|
7
12
|
};
|
|
8
13
|
|
|
9
14
|
export class StringParserInputCompanion implements ParserInputCompanion<string, string> {
|
|
@@ -15,6 +20,10 @@ export class StringParserInputCompanion implements ParserInputCompanion<string,
|
|
|
15
20
|
return elements.join('');
|
|
16
21
|
}
|
|
17
22
|
|
|
23
|
+
concat(sequences: string[]): string {
|
|
24
|
+
return sequences.join('');
|
|
25
|
+
}
|
|
26
|
+
|
|
18
27
|
length(sequence: string): number {
|
|
19
28
|
return sequence.length;
|
|
20
29
|
}
|
|
@@ -22,6 +31,22 @@ export class StringParserInputCompanion implements ParserInputCompanion<string,
|
|
|
22
31
|
at(sequence: string, index: number): string | undefined {
|
|
23
32
|
return sequence.at(index);
|
|
24
33
|
}
|
|
34
|
+
|
|
35
|
+
subsequence(sequence: string, start: number, end: number): string {
|
|
36
|
+
return sequence.slice(start, end);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
indexOf(sequence: string, element: string, fromIndex?: number): number {
|
|
40
|
+
return sequence.indexOf(element, fromIndex);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
indexOfSubsequence(sequence: string, subsequence: string, fromIndex?: number): number {
|
|
44
|
+
return sequence.indexOf(subsequence, fromIndex);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
equals(sequenceA: string, sequenceB: string): boolean {
|
|
48
|
+
return sequenceA === sequenceB;
|
|
49
|
+
}
|
|
25
50
|
}
|
|
26
51
|
|
|
27
52
|
export const stringParserInputCompanion = new StringParserInputCompanion();
|
|
@@ -35,6 +60,10 @@ export class Uint8ArrayParserInputCompanion implements ParserInputCompanion<Uint
|
|
|
35
60
|
return new Uint8Array(elements);
|
|
36
61
|
}
|
|
37
62
|
|
|
63
|
+
concat(sequences: Uint8Array[]): Uint8Array {
|
|
64
|
+
return new Uint8Array(Buffer.concat(sequences));
|
|
65
|
+
}
|
|
66
|
+
|
|
38
67
|
length(sequence: Uint8Array): number {
|
|
39
68
|
return sequence.length;
|
|
40
69
|
}
|
|
@@ -42,6 +71,32 @@ export class Uint8ArrayParserInputCompanion implements ParserInputCompanion<Uint
|
|
|
42
71
|
at(sequence: Uint8Array, index: number): number | undefined {
|
|
43
72
|
return sequence.at(index);
|
|
44
73
|
}
|
|
74
|
+
|
|
75
|
+
subsequence(sequence: Uint8Array, start: number, end: number): Uint8Array {
|
|
76
|
+
return sequence.subarray(start, end);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
indexOf(sequence: Uint8Array, element: number, fromIndex?: number): number {
|
|
80
|
+
return sequence.indexOf(element, fromIndex);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
indexOfSubsequence(sequence: Uint8Array, subsequence: Uint8Array, fromIndex?: number): number {
|
|
84
|
+
return Buffer.from(sequence).indexOf(Buffer.from(subsequence), fromIndex);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
equals(sequenceA: Uint8Array, sequenceB: Uint8Array): boolean {
|
|
88
|
+
if (sequenceA.length !== sequenceB.length) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for (const [ index, element ] of sequenceA.entries()) {
|
|
93
|
+
if (element !== sequenceB[index]) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
45
100
|
}
|
|
46
101
|
|
|
47
102
|
export const uint8ArrayParserInputCompanion = new Uint8ArrayParserInputCompanion();
|
package/src/promiseCompose.ts
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
|
|
2
2
|
export function promiseCompose<A, B, C>(
|
|
3
|
-
f1: (a: A) => Promise<B>,
|
|
3
|
+
f1: (a: A) => B | Promise<B>,
|
|
4
4
|
f2: (b: B) => C | Promise<C>,
|
|
5
|
-
): (a: A) => Promise<C> {
|
|
6
|
-
|
|
5
|
+
): (a: A) => C | Promise<C> {
|
|
6
|
+
async function promiseComposed(a: A) {
|
|
7
|
+
const bOrBPromise = f1(a);
|
|
8
|
+
|
|
9
|
+
if (bOrBPromise instanceof Promise) {
|
|
10
|
+
return bOrBPromise.then(f2);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return f2(bOrBPromise);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
Object.defineProperty(promiseComposed, 'name', {
|
|
17
|
+
value: `promiseCompose(${f1.name}, ${f2.name})`,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
return promiseComposed;
|
|
7
21
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { testProp, fc } from '@fast-check/ava';
|
|
3
|
+
import { createSeparatedArrayParser } from './separatedArrayParser.js';
|
|
4
|
+
import { type Parser, runParser, runParserWithRemainingInput } from './parser.js';
|
|
5
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
6
|
+
import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
7
|
+
|
|
8
|
+
test('does not loop forever with a child parser that does not consume anything', async t => {
|
|
9
|
+
const parser: Parser<undefined[], string> = createSeparatedArrayParser(async () => undefined, () => undefined);
|
|
10
|
+
const { output } = await runParserWithRemainingInput(parser, 'foo', stringParserInputCompanion);
|
|
11
|
+
|
|
12
|
+
t.deepEqual(output, []);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
testProp(
|
|
16
|
+
'separatedArray',
|
|
17
|
+
[
|
|
18
|
+
fc.array(fc.constant('element')),
|
|
19
|
+
],
|
|
20
|
+
async (t, elements) => {
|
|
21
|
+
const separatedArrayParser = createSeparatedArrayParser(
|
|
22
|
+
createExactSequenceParser('element'),
|
|
23
|
+
createExactSequenceParser('separator'),
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const actual = await runParser(separatedArrayParser, elements.join('separator'), stringParserInputCompanion);
|
|
27
|
+
const expected = elements;
|
|
28
|
+
|
|
29
|
+
t.deepEqual(actual, expected);
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
verbose: true,
|
|
33
|
+
},
|
|
34
|
+
);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { getParserName, type Parser, setParserName } from './parser.js';
|
|
2
|
+
import { isParserParsingFailedError } from './parserError.js';
|
|
3
|
+
import { promiseCompose } from './promiseCompose.js';
|
|
4
|
+
import { createTupleParser } from './tupleParser.js';
|
|
5
|
+
|
|
6
|
+
export const createSeparatedArrayParser = <ElementOutput, Sequence>(
|
|
7
|
+
elementParser: Parser<ElementOutput, Sequence>,
|
|
8
|
+
separatorParser: Parser<unknown, Sequence>,
|
|
9
|
+
): Parser<ElementOutput[], Sequence> => {
|
|
10
|
+
const separatorThenElementParser: Parser<ElementOutput, Sequence> = promiseCompose(
|
|
11
|
+
createTupleParser([
|
|
12
|
+
separatorParser,
|
|
13
|
+
elementParser,
|
|
14
|
+
]),
|
|
15
|
+
([ , element ]) => element,
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const separatedArrayParser: Parser<ElementOutput[], Sequence> = async parserContext => {
|
|
19
|
+
let parser = elementParser;
|
|
20
|
+
|
|
21
|
+
const elements: ElementOutput[] = [];
|
|
22
|
+
|
|
23
|
+
while (true) {
|
|
24
|
+
const elementParserContext = parserContext.lookahead();
|
|
25
|
+
const initialPosition = elementParserContext.position;
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const element = await parser(elementParserContext);
|
|
29
|
+
|
|
30
|
+
if (elementParserContext.position === initialPosition) {
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
elements.push(element);
|
|
35
|
+
elementParserContext.unlookahead();
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (isParserParsingFailedError(error)) {
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
throw error;
|
|
42
|
+
} finally {
|
|
43
|
+
elementParserContext.dispose();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
parser = separatorThenElementParser;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return elements;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
setParserName(separatedArrayParser, getParserName(elementParser, 'anonymousSeparatedArrayChild') + '*');
|
|
53
|
+
|
|
54
|
+
return separatedArrayParser;
|
|
55
|
+
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { testProp, fc } from '@fast-check/ava';
|
|
3
|
+
import { createSeparatedNonEmptyArrayParser } from './separatedNonEmptyArrayParser.js';
|
|
4
|
+
import { type Parser, runParser, runParserWithRemainingInput } from './parser.js';
|
|
5
|
+
import { stringParserInputCompanion } from './parserInputCompanion.js';
|
|
6
|
+
import { createExactSequenceParser } from './exactSequenceParser.js';
|
|
7
|
+
import { stringFromAsyncIterable } from './stringFromAsyncIterable.js';
|
|
8
|
+
|
|
9
|
+
test('empty input throws error', async t => {
|
|
10
|
+
const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
|
|
11
|
+
createExactSequenceParser('element'),
|
|
12
|
+
createExactSequenceParser(','),
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
await t.throwsAsync(async () => runParser(parser, '', stringParserInputCompanion), {
|
|
16
|
+
any: true,
|
|
17
|
+
message: /Expected .* to match at least once/,
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('single element without separator matches', async t => {
|
|
22
|
+
const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
|
|
23
|
+
createExactSequenceParser('element'),
|
|
24
|
+
createExactSequenceParser(','),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const result = await runParser(parser, 'element', stringParserInputCompanion);
|
|
28
|
+
t.deepEqual(result, [ 'element' ]);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('two elements with separator matches', async t => {
|
|
32
|
+
const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
|
|
33
|
+
createExactSequenceParser('element'),
|
|
34
|
+
createExactSequenceParser(','),
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const result = await runParser(parser, 'element,element', stringParserInputCompanion);
|
|
38
|
+
t.deepEqual(result, [ 'element', 'element' ]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('multiple elements with separator matches', async t => {
|
|
42
|
+
const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
|
|
43
|
+
createExactSequenceParser('a'),
|
|
44
|
+
createExactSequenceParser(','),
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const result = await runParser(parser, 'a,a,a,a', stringParserInputCompanion);
|
|
48
|
+
t.deepEqual(result, [ 'a', 'a', 'a', 'a' ]);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('does not consume trailing separator', async t => {
|
|
52
|
+
const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
|
|
53
|
+
createExactSequenceParser('element'),
|
|
54
|
+
createExactSequenceParser(','),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const { output, remainingInput } = await runParserWithRemainingInput(parser, 'element,element,', stringParserInputCompanion);
|
|
58
|
+
t.deepEqual(output, [ 'element', 'element' ]);
|
|
59
|
+
t.is(await stringFromAsyncIterable(remainingInput!), ',');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('does not loop forever with a child parser that does not consume anything', async t => {
|
|
63
|
+
const parser: Parser<undefined[], string> = createSeparatedNonEmptyArrayParser(
|
|
64
|
+
async () => undefined,
|
|
65
|
+
() => undefined,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
await t.throwsAsync(async () => runParser(parser, 'foo', stringParserInputCompanion), {
|
|
69
|
+
any: true,
|
|
70
|
+
message: /Expected .* to match at least once/,
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('partial match throws error', async t => {
|
|
75
|
+
const parser: Parser<string[], string> = createSeparatedNonEmptyArrayParser(
|
|
76
|
+
createExactSequenceParser('element'),
|
|
77
|
+
createExactSequenceParser(','),
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
await t.throwsAsync(async () => runParser(parser, 'elem', stringParserInputCompanion), {
|
|
81
|
+
any: true,
|
|
82
|
+
message: /Expected .* to match at least once/,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
testProp(
|
|
87
|
+
'separatedNonEmptyArray with at least one element',
|
|
88
|
+
[
|
|
89
|
+
fc.array(fc.constant('element'), { minLength: 1 }),
|
|
90
|
+
],
|
|
91
|
+
async (t, elements) => {
|
|
92
|
+
const separatedNonEmptyArrayParser = createSeparatedNonEmptyArrayParser(
|
|
93
|
+
createExactSequenceParser('element'),
|
|
94
|
+
createExactSequenceParser('separator'),
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const actual = await runParser(separatedNonEmptyArrayParser, elements.join('separator'), stringParserInputCompanion);
|
|
98
|
+
const expected = elements;
|
|
99
|
+
|
|
100
|
+
t.deepEqual(actual, expected);
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
verbose: true,
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
test('separatedNonEmptyArray throws on empty array', async t => {
|
|
108
|
+
const separatedNonEmptyArrayParser = createSeparatedNonEmptyArrayParser(
|
|
109
|
+
createExactSequenceParser('element'),
|
|
110
|
+
createExactSequenceParser('separator'),
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
await t.throwsAsync(async () => runParser(separatedNonEmptyArrayParser, '', stringParserInputCompanion), {
|
|
114
|
+
any: true,
|
|
115
|
+
message: /Expected .* to match at least once/,
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { getParserName, type Parser, setParserName } from './parser.js';
|
|
2
|
+
import { isParserParsingFailedError, ParserParsingFailedError } from './parserError.js';
|
|
3
|
+
import { promiseCompose } from './promiseCompose.js';
|
|
4
|
+
import { createTupleParser } from './tupleParser.js';
|
|
5
|
+
|
|
6
|
+
export const createSeparatedNonEmptyArrayParser = <ElementOutput, Sequence>(
|
|
7
|
+
elementParser: Parser<ElementOutput, Sequence>,
|
|
8
|
+
separatorParser: Parser<unknown, Sequence>,
|
|
9
|
+
): Parser<ElementOutput[], Sequence> => {
|
|
10
|
+
const separatorThenElementParser: Parser<ElementOutput, Sequence> = promiseCompose(
|
|
11
|
+
createTupleParser([
|
|
12
|
+
separatorParser,
|
|
13
|
+
elementParser,
|
|
14
|
+
]),
|
|
15
|
+
([ , element ]) => element,
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const separatedNonEmptyArrayParser: Parser<ElementOutput[], Sequence> = async parserContext => {
|
|
19
|
+
let parser = elementParser;
|
|
20
|
+
|
|
21
|
+
const elements: ElementOutput[] = [];
|
|
22
|
+
|
|
23
|
+
while (true) {
|
|
24
|
+
const elementParserContext = parserContext.lookahead();
|
|
25
|
+
const initialPosition = elementParserContext.position;
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const element = await parser(elementParserContext);
|
|
29
|
+
|
|
30
|
+
if (elementParserContext.position === initialPosition) {
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
elements.push(element);
|
|
35
|
+
elementParserContext.unlookahead();
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (isParserParsingFailedError(error)) {
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
throw error;
|
|
42
|
+
} finally {
|
|
43
|
+
elementParserContext.dispose();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
parser = separatorThenElementParser;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
parserContext.invariant(
|
|
50
|
+
elements.length > 0,
|
|
51
|
+
'Expected elementParser (%s) to match at least once',
|
|
52
|
+
getParserName(elementParser, 'anonymousSeparatedNonEmptyArrayChild'),
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return elements;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
setParserName(separatedNonEmptyArrayParser, getParserName(elementParser, 'anonymousSeparatedNonEmptyArrayChild') + '+');
|
|
59
|
+
|
|
60
|
+
return separatedNonEmptyArrayParser;
|
|
61
|
+
};
|