Skip to content

Commit 5678ad2

Browse files
committed
Improve message produced by eitherResult for Partial
When a parser result is Partial, previously the eitherResult function showed a generic error message that includes no useful information other than a generic "incomplete input" message. For example, if we let p = (,) <$> letter <*> digit <?> "thing" then eitherResult (parse p "a") = Left "Result: incomplete input" Attoparsec is already capable of generating more informative error information for this example, as we can demonstrate by using parseOnly: parseOnly p "a" = "thing > digit: not enough input" This change brings that same error message to eitherResult by simply feeding `mempty` into the continuation. With this change, eitherResult now gives the same output as parseOnly. eitherResult (parse p "a") = "thing > digit: not enough input"
1 parent 71a67cb commit 5678ad2

File tree

4 files changed

+26
-8
lines changed

4 files changed

+26
-8
lines changed

Data/Attoparsec/ByteString.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ maybeResult _ = Nothing
226226
-- | Convert a 'Result' value to an 'Either' value. A 'T.Partial'
227227
-- result is treated as failure.
228228
eitherResult :: Result r -> Either String r
229-
eitherResult (T.Done _ r) = Right r
230-
eitherResult (T.Fail _ [] msg) = Left msg
231-
eitherResult (T.Fail _ ctxs msg) = Left (intercalate " > " ctxs ++ ": " ++ msg)
232-
eitherResult _ = Left "Result: incomplete input"
229+
eitherResult result = case feed result B.empty of
230+
T.Done _ r -> Right r
231+
T.Fail _ [] msg -> Left msg
232+
T.Fail _ ctxs msg -> Left (intercalate " > " ctxs ++ ": " ++ msg)
233+
T.Partial _ -> error "eitherResult: Partial"

Data/Attoparsec/Text.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,11 @@ maybeResult _ = Nothing
266266
-- | Convert a 'Result' value to an 'Either' value. A 'Partial' result
267267
-- is treated as failure.
268268
eitherResult :: Result r -> Either String r
269-
eitherResult (T.Done _ r) = Right r
270-
eitherResult (T.Fail _ [] msg) = Left msg
271-
eitherResult (T.Fail _ ctxs msg) = Left (intercalate " > " ctxs ++ ": " ++ msg)
272-
eitherResult _ = Left "Result: incomplete input"
269+
eitherResult result = case feed result T.empty of
270+
T.Done _ r -> Right r
271+
T.Fail _ [] msg -> Left msg
272+
T.Fail _ ctxs msg -> Left (intercalate " > " ctxs ++ ": " ++ msg)
273+
T.Partial _ -> error "eitherResult: Partial"
273274

274275
-- | A predicate that matches either a carriage return @\'\\r\'@ or
275276
-- newline @\'\\n\'@ character.

tests/QC/ByteString.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ nonmembers :: [Word8] -> [Word8] -> Property
182182
nonmembers s s' = property . not . any (`S.memberWord8` set) $ filter (not . (`elem` s)) s'
183183
where set = S.fromList s
184184

185+
eitherResultPartialError :: Property
186+
eitherResultPartialError = P.eitherResult (P.parse p input) === Left msg
187+
where
188+
p = (,) <$> P8.letter_ascii <*> P8.digit P.<?> "thing"
189+
input = "a"
190+
msg = "thing > digit: not enough input"
191+
185192
tests :: [TestTree]
186193
tests = [
187194
testProperty "anyWord8" anyWord8
@@ -211,4 +218,5 @@ tests = [
211218
, testProperty "word8" word8
212219
, testProperty "members" members
213220
, testProperty "nonmembers" nonmembers
221+
, testProperty "eitherResultPartialError" eitherResultPartialError
214222
]

tests/QC/Text.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ nonmembers :: String -> String -> Property
170170
nonmembers s s' = property . not . any (`S.member` set) $ filter (not . (`elem` s)) s'
171171
where set = S.fromList s
172172

173+
eitherResultPartialError :: Property
174+
eitherResultPartialError = P.eitherResult (P.parse p input) === Left msg
175+
where
176+
input = "a"
177+
p = (,) <$> P.letter <*> P.digit P.<?> "thing"
178+
msg = "thing > digit: not enough input"
179+
173180
tests :: [TestTree]
174181
tests = [
175182
testProperty "anyChar" anyChar
@@ -198,6 +205,7 @@ tests = [
198205
, testProperty "takeWhile1_empty" takeWhile1_empty
199206
, testProperty "members" members
200207
, testProperty "nonmembers" nonmembers
208+
, testProperty "eitherResultPartialError" eitherResultPartialError
201209
, testGroup "FastSet" FastSet.tests
202210
, testGroup "Regressions" Regressions.tests
203211
]

0 commit comments

Comments
 (0)