From 2ce39494c7050654096731011a9d7afbec6149b0 Mon Sep 17 00:00:00 2001 From: pinkjuice66 Date: Wed, 6 Dec 2023 01:36:44 +0900 Subject: [PATCH 1/2] Fix error message StartsWith parser throws --- Sources/Parsing/ParserPrinters/StartsWith.swift | 2 +- Sources/Parsing/ParsingError.swift | 3 +++ Tests/ParsingTests/StartsWithTests.swift | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Sources/Parsing/ParserPrinters/StartsWith.swift b/Sources/Parsing/ParserPrinters/StartsWith.swift index d21568f005..e0f9245dba 100644 --- a/Sources/Parsing/ParserPrinters/StartsWith.swift +++ b/Sources/Parsing/ParserPrinters/StartsWith.swift @@ -63,7 +63,7 @@ public struct StartsWith: Parser where Input.SubSequence == I @inlinable public func parse(_ input: inout Input) throws { guard self.startsWith(input) else { - throw ParsingError.expectedInput(formatValue(self.possiblePrefix), at: input) + throw ParsingError.expectedInput("\"\(formatValue(self.possiblePrefix))\"", at: input) } input.removeFirst(self.count) } diff --git a/Sources/Parsing/ParsingError.swift b/Sources/Parsing/ParsingError.swift index 5c03dbc674..9f71b8455f 100644 --- a/Sources/Parsing/ParsingError.swift +++ b/Sources/Parsing/ParsingError.swift @@ -415,6 +415,9 @@ func formatValue( case let input as Substring.UTF8View: return Substring(input).debugDescription + + case let input as AnyCollection: + return String(bytes: input, encoding: .utf8) ?? "\(input)" default: return "\(input)" diff --git a/Tests/ParsingTests/StartsWithTests.swift b/Tests/ParsingTests/StartsWithTests.swift index 00310b564a..1eff9a6092 100644 --- a/Tests/ParsingTests/StartsWithTests.swift +++ b/Tests/ParsingTests/StartsWithTests.swift @@ -7,4 +7,19 @@ final class StartsWithTests: XCTestCase { XCTAssertNoThrow(try StartsWith("Hello".utf8).parse(&str)) XCTAssertEqual(", world!", Substring(str)) } + + func testParseFailure() { + var input = "Goodnight, Blob!"[...].utf8 + XCTAssertThrowsError(try StartsWith("Hello, ".utf8).parse(&input)) { error in + XCTAssertEqual( + """ + error: unexpected input + --> input:1:1 + 1 | Goodnight, Blob! + | ^ expected "Hello, " + """, + "\(error)" + ) + } + } } From 824425b01cd69ad8e1031e29a467e1dcfdfe7023 Mon Sep 17 00:00:00 2001 From: pinkjuice66 Date: Wed, 6 Dec 2023 03:56:37 +0900 Subject: [PATCH 2/2] preserve possiblePrefix value with original type --- Sources/Parsing/ParserPrinters/StartsWith.swift | 4 +++- Sources/Parsing/ParsingError.swift | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Sources/Parsing/ParserPrinters/StartsWith.swift b/Sources/Parsing/ParserPrinters/StartsWith.swift index e0f9245dba..22e24816d1 100644 --- a/Sources/Parsing/ParserPrinters/StartsWith.swift +++ b/Sources/Parsing/ParserPrinters/StartsWith.swift @@ -39,6 +39,7 @@ public struct StartsWith: Parser where Input.SubSequence == Input { public let count: Int public let possiblePrefix: AnyCollection + public let originalPossiblePrefix: Any public let startsWith: (Input) -> Bool /// Initializes a parser that successfully returns `Void` when the initial elements of its input @@ -57,13 +58,14 @@ public struct StartsWith: Parser where Input.SubSequence == I where PossiblePrefix.Element == Input.Element { self.count = possiblePrefix.count self.possiblePrefix = AnyCollection(possiblePrefix) + self.originalPossiblePrefix = possiblePrefix self.startsWith = { input in input.starts(with: possiblePrefix, by: areEquivalent) } } @inlinable public func parse(_ input: inout Input) throws { guard self.startsWith(input) else { - throw ParsingError.expectedInput("\"\(formatValue(self.possiblePrefix))\"", at: input) + throw ParsingError.expectedInput(formatValue(self.originalPossiblePrefix), at: input) } input.removeFirst(self.count) } diff --git a/Sources/Parsing/ParsingError.swift b/Sources/Parsing/ParsingError.swift index 9f71b8455f..5c03dbc674 100644 --- a/Sources/Parsing/ParsingError.swift +++ b/Sources/Parsing/ParsingError.swift @@ -415,9 +415,6 @@ func formatValue( case let input as Substring.UTF8View: return Substring(input).debugDescription - - case let input as AnyCollection: - return String(bytes: input, encoding: .utf8) ?? "\(input)" default: return "\(input)"