{-# LANGUAGE CPP #-} {-# LANGUAGE LambdaCase #-} -- | Definition of the parsing monad, plus internal -- unsafe functions. module Data.ProtoLens.Encoding.Parser.Internal ( Parser(..) , ParseResult(..) ) where import Control.Monad (ap) import qualified Control.Monad.Fail as Fail import Data.Word (Word8) import Foreign.Ptr -- | A monad for parsing an input buffer. newtype Parser a = Parser { unParser :: Ptr Word8 -- End position of the input -> Ptr Word8 -- Current position in the input -> IO (ParseResult a) } data ParseResult a = ParseSuccess { _newPos :: !(Ptr Word8) -- ^ New position in the input , unParserResult :: a } | ParseFailure String instance Functor ParseResult where fmap f (ParseSuccess p x) = ParseSuccess p (f x) fmap _ (ParseFailure s) = ParseFailure s instance Functor Parser where fmap f (Parser g) = Parser $ \end cur -> fmap f <$> g end cur instance Applicative Parser where pure x = Parser $ \_ cur -> return $ ParseSuccess cur x (<*>) = ap instance Monad Parser where #if !MIN_VERSION_base(4,13,0) fail = Fail.fail #endif return = pure Parser f >>= g = Parser $ \end pos -> f end pos >>= \case ParseSuccess pos' x -> unParser (g x) end pos' ParseFailure s -> return $ ParseFailure s instance Fail.MonadFail Parser where fail s = Parser $ \_ _ -> return $ ParseFailure s