{-# LANGUAGE LambdaCase #-}

module Internal.Text.Read where

import Control.Monad
    ( replicateM_ )
import Text.Read
    ( ReadPrec, get, look, pfail )

import qualified Data.List as L

readCharMaybe :: (Char -> Maybe a) -> ReadPrec a
readCharMaybe :: forall a. (Char -> Maybe a) -> ReadPrec a
readCharMaybe Char -> Maybe a
f = ReadPrec String
look forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Char
a : String
_ | Just a
c <- Char -> Maybe a
f Char
a ->
        ReadPrec Char
get forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (f :: * -> *) a. Applicative f => a -> f a
pure a
c
    String
_ ->
        forall a. ReadPrec a
pfail

skipChar :: Char -> ReadPrec ()
skipChar :: Char -> ReadPrec ()
skipChar Char
charToSkip = forall a. (Char -> Maybe a) -> ReadPrec a
readCharMaybe
    (\Char
char -> if Char
char forall a. Eq a => a -> a -> Bool
== Char
charToSkip then forall a. a -> Maybe a
Just () else forall a. Maybe a
Nothing)

skipString :: String -> ReadPrec ()
skipString :: String -> ReadPrec ()
skipString String
stringToSkip = do
    String
remainder <- ReadPrec String
look
    if String
stringToSkip forall a. Eq a => [a] -> [a] -> Bool
`L.isPrefixOf` String
remainder
    then forall (m :: * -> *) a. Applicative m => Int -> m a -> m ()
replicateM_ (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
stringToSkip) ReadPrec Char
get
    else forall a. ReadPrec a
pfail