module Strelka.ParamsParsing.Value
where
import Strelka.Prelude hiding (maybe, list)
import qualified Data.Attoparsec.Text as G
import qualified Data.Text as E
import qualified Attoparsec.Data as B
newtype Value a =
Value (ReaderT [Text] (Except Text) a)
deriving (Functor, Applicative, Alternative)
{-# INLINE parser #-}
parser :: G.Parser a -> Value a
parser parser =
matcher (first fromString . G.parseOnly finishedParser)
where
finishedParser =
parser <* (G.endOfInput <|> fail "Didn't parse the whole data")
{-# INLINE matcher #-}
matcher :: (Text -> Either Text a) -> Value a
matcher matcher =
Value (ReaderT (except . join . liftM matcher . head))
where
head =
\case
x : _ -> Right x
_ -> Left ("Not a single value is specified")
{-# INLINE text #-}
text :: Value Text
text =
matcher Right
{-# INLINE string #-}
string :: Value String
string =
matcher (Right . E.unpack)
{-# INLINE list #-}
list :: Value a -> Value [a]
list (Value (ReaderT singleValueFn)) =
Value (ReaderT (traverse (singleValueFn . pure)))
{-# INLINE maybe #-}
maybe :: Value a -> Value (Maybe a)
maybe (Value (ReaderT singleValueFn)) =
Value (ReaderT (traverse (singleValueFn . pure) . listToMaybe))
{-# INLINE bool #-}
bool :: Value Bool
bool =
fromMaybe False <$> maybe (parser B.lenientParser)