pipes-attoparsec-0.1.0.1: src/Control/Proxy/Attoparsec/Types.hs
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE KindSignatures #-}
-- | This module exports common types used throughout
-- @"Control.Proxy.Attoparsec".*@
module Control.Proxy.Attoparsec.Types
( -- * Proxy control
ParserStatus(..)
, SupplyUse(..)
, ParserSupply
-- * Error types
, BadInput(..)
-- * Attoparsec integration
, AttoparsecInput(..)
, ParserError(..)
) where
import qualified Data.Attoparsec.ByteString as ABS
import qualified Data.Attoparsec.Text as AT
import Data.Attoparsec.Types
import qualified Data.ByteString as BS
import qualified Data.Text as T
-- | Status of a parsing 'Proxy'.
data ParserStatus a
-- | There is a 'Parser' running and waiting for more @a@ input.
--
-- Receiving @('Resume', a)@ from upstream would feed input @a@ to the 'Parser'
-- waiting for more input.
= Parsing
{ psLength :: Int -- ^Length of input consumed so far.
}
-- | A 'Parser' has failed parsing.
--
-- Receiving @('Resume', a)@ from upstream would feed input @a@ to a newly
-- started 'Parser'.
| Failed
{ psLeftover :: a -- ^Input not yet consumed when the failure occurred.
, psError :: ParserError -- ^Error found while parsing.
}
deriving (Show, Eq)
data ParserError = ParserError
{ errorContexts :: [String] -- ^ Contexts where the error occurred.
, errorMessage :: String -- ^ Error message.
} deriving (Show, Eq)
-- | Indicates how should a parsing 'Proxy' use new input.
data SupplyUse
-- | Start a new parser and fed any new input to it.
= Start
-- | Resume feeding any new input to the current parser waiting for input.
| Resume
deriving (Eq, Show)
-- | Input supplied to a parsing 'Proxy'.
--
-- The 'SupplyUse' value indicates how the @a@ input chunk should be used.
type ParserSupply a = (SupplyUse, a)
-- | Reasons for an input value to be unnaceptable.
data BadInput
= InputTooLong
{ itlLength :: Int -- ^ Length of the input.
}
| MalformedInput
{ miParserErrror :: ParserError -- ^ Error found while parsing.
}
deriving (Show, Eq)
-- | A class for valid Attoparsec input types.
class Eq a => AttoparsecInput a where
-- | Run a 'Parser' with input @a@.
parse :: Parser a b -> a -> IResult a b
-- | Tests whether @a@ is empty.
null :: a -> Bool
-- | Skips the first @n@ elements from @a@ and returns the rest.
drop :: Int -> a -> a
-- | Number of elements in @a@.
length :: a -> Int
instance AttoparsecInput BS.ByteString where
parse = ABS.parse
null = BS.null
drop = BS.drop
length = BS.length
instance AttoparsecInput T.Text where
parse = AT.parse
null = T.null
drop = T.drop
length = T.length