packages feed

attoparsec-run (empty) → 0.0.0.0

raw patch · 7 files changed

+227/−0 lines, 7 filesdep +attoparsecdep +basedep +bytestring

Dependencies added: attoparsec, base, bytestring, text

Files

+ attoparsec-run.cabal view
@@ -0,0 +1,45 @@+cabal-version: 3.0++name: attoparsec-run+version: 0.0.0.0+synopsis: Conveniently run Attoparsec parsers+category: Parsing++description: This package fixes a number of problems with the API that+    Attoparsec provides for running parsers. The difficulties stem from+    the that that Attoparsec's @IResult@ type encompasses three situations:+    When parsing has succeeded, when parsing has failed, and when parsing+    is awaiting further input. This is insufficient to describe situations+    in which we know we are dealing with a subset of these three cases.+    We address this by introducing two smaller types: @FinalResult@ and+    @ParseError@.++license: Apache-2.0+license-file: license.txt++author: Chris Martin+maintainer: Chris Martin, Julie Moronuki++homepage: https://github.com/typeclasses/attoparsec-run+bug-Reports: https://github.com/typeclasses/attoparsec-run/issues++extra-source-files: *.md++source-repository head+    type: git+    location: git://github.com/typeclasses/attoparsec-run.git++library+    default-language: Haskell2010+    ghc-options: -Wall+    hs-source-dirs: library+    build-depends:+      , attoparsec ^>= 0.14.4+      , base ^>= 4.14 || ^>= 4.15 || ^>= 4.16 || ^>= 4.17+      , bytestring ^>= 0.10.12 || ^>= 0.11+      , text ^>= 1.2.4 || ^>= 2.0+    exposed-modules:+        Data.Attoparsec.Run++        Data.Attoparsec.ByteString.Run+        Data.Attoparsec.Text.Run
+ changelog.md view
@@ -0,0 +1,3 @@+### 0.0.0.0 (2023-01-09)++Initial release
+ library/Data/Attoparsec/ByteString/Run.hs view
@@ -0,0 +1,26 @@+module Data.Attoparsec.ByteString.Run+  (+    parseStream, parseAndRestore,+    module Data.Attoparsec.Run,+  )+  where++import Data.Attoparsec.Run++import Control.Monad (unless)+import Data.Attoparsec.ByteString (parseWith, Parser)+import Data.ByteString (ByteString)+import Data.ByteString (null)+import Prelude (($), (<$>), pure, mempty, Monad, Either)++parseStream :: Monad m =>+    BufferedInput m ByteString -> Parser a -> m (FinalResult ByteString a)+parseStream (BufferedInput initial get) p =+    finalizeResult <$> parseWith get p initial++parseAndRestore :: Monad m =>+    RestorableInput m ByteString -> Parser a -> m (Either ParseError a)+parseAndRestore (RestorableInput get restore) p = do+    FinalResult remainder value <- parseStream (BufferedInput mempty get) p+    unless (null remainder) $ restore remainder+    pure value
+ library/Data/Attoparsec/Run.hs view
@@ -0,0 +1,41 @@+module Data.Attoparsec.Run where++import Data.Attoparsec.Types++import Data.List (intercalate)+import Prelude (Either (..), Eq, Ord, Show, String, error, otherwise, null, (++))++data FinalResult i a = FinalResult+    i -- ^ Remaining unparsed input+    (Either ParseError a) -- ^ Either an error or a successfully parsed value+    deriving (Eq, Ord, Show)++finalizeResult ::+    IResult i a -- ^ Must be either 'Done' or 'Fail', not 'Partial'+    -> FinalResult i a+finalizeResult r = case r of+    Done remainder v ->+        FinalResult remainder (Right v)+    Fail remainder context message ->+        FinalResult remainder (Left (ParseError context message))+    Partial{} ->+        error "parseWith should not return Partial"++data ParseError = ParseError+    [String] -- ^ A list of contexts in which the error occurred+    String -- ^ The message describing the error, if any+    deriving (Eq, Ord, Show)++-- | Format a parse error in a matter suitable for displaying in log output+showParseError :: ParseError -> String+showParseError (ParseError context message)+    | null context = message+    | otherwise = intercalate " > " context ++ ": " ++ message++data BufferedInput m i = BufferedInput+    i -- ^ Initial input+    (m i) -- ^ Should return an empty string once the end of input is reached++data RestorableInput m i = RestorableInput+    (m i) -- ^ Return an empty string once the end of input is reached+    (i -> m ()) -- ^ Return a non-empty chunk of input to the input stream
+ library/Data/Attoparsec/Text/Run.hs view
@@ -0,0 +1,26 @@+module Data.Attoparsec.Text.Run+  (+    parseStream, parseAndRestore,+    module Data.Attoparsec.Run,+  )+  where++import Data.Attoparsec.Run++import Control.Monad (unless)+import Data.Attoparsec.Text (parseWith, Parser)+import Data.Text (Text)+import Data.Text (null)+import Prelude (($), (<$>), pure, mempty, Monad, Either)++parseStream :: Monad m =>+    BufferedInput m Text -> Parser a -> m (FinalResult Text a)+parseStream (BufferedInput initial get) p =+    finalizeResult <$> parseWith get p initial++parseAndRestore :: Monad m =>+    RestorableInput m Text -> Parser a -> m (Either ParseError a)+parseAndRestore (RestorableInput get restore) p = do+    FinalResult remainder value <- parseStream (BufferedInput mempty get) p+    unless (null remainder) $ restore remainder+    pure value
+ license.txt view
@@ -0,0 +1,13 @@+Copyright 2023 Mission Valley Software LLC++Licensed under the Apache License, Version 2.0 (the "License");+you may not use this file except in compliance with the License.+You may obtain a copy of the License at++    http://www.apache.org/licenses/LICENSE-2.0++Unless required by applicable law or agreed to in writing, software+distributed under the License is distributed on an "AS IS" BASIS,+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+See the License for the specific language governing permissions and+limitations under the License.
+ readme.md view
@@ -0,0 +1,73 @@+This package fixes a number of problems with the API that Attoparsec provides+for running parsers.++The difficulties stem from the that that Attoparsec's `IResult` type encompasses+three situations: When parsing has succeeded, when parsing has failed, and when+parsing is awaiting further input. This is insufficient to describe situations+in which we know we are dealing with a subset of these three cases. We address+this by introducing two smaller types: `FinalResult` and `ParseError`.++### FinalResult++`FinalResult` represents a result that we know not to be partial; for example,+the sort of result that we get when running a parser using `parseWith`.++```haskell+data FinalResult i a = FinalResult i (Either ParseError a)+```++### ParseError++`ParseError` represents only the case in which parsing has failed.++```haskell+data ParseError = ParseError [String] String+```++Our `showParseError` function gives an error string in the same format as+Attoparsec's `eitherResult` function.++```haskell+showParseError :: ParseError -> String+```++### BufferedInput++The `BufferedInput` type corresponds to two arguments of Attoparsec's+`parseWith`, the initial input and the action to obtain more input.++```haskell+data BufferedInput m i = BufferedInput i (m i)+```++In each of the modules `Data.Attoparsec.ByteString.Run` and+`Data.Attoparsec.Text.Run`, we provide a function called `parseStream`. This+closely corresponds to Attoparsec's `parseWith` function, but ours returns the+more specific `FinalResult` type, rather than `Result`, reflecting the fact that+a result returned here is never partial.++```haskell+parseStream :: Monad m =>+    BufferedInput m ByteString -> Parser a -> m (FinalResult ByteString a)+```++### RestorableInput++`RestorableInput` offers a new way to do streaming parsing that may be more+convenient than `parseStream` and `BufferedInput`. This type represents an input+stream with the ability to push unused input back to it.++```haskell+data RestorableInput m i = RestorableInput (m i) (i -> m ())+```++We use this type with the `parseAndRestore` function:++```haskell+parseAndRestore :: Monad m =>+    RestorableInput m ByteString -> Parser a -> m (Either ParseError a)+```++This shifts the burden of storing the unused remainder to feed back into the+next parsing step from the user of `parseStream` to the definer of the+`RestorableInput`.