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)
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")
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")
text :: Value Text
text =
matcher Right
string :: Value String
string =
matcher (Right . E.unpack)
list :: Value a -> Value [a]
list (Value (ReaderT singleValueFn)) =
Value (ReaderT (traverse (singleValueFn . pure)))
maybe :: Value a -> Value (Maybe a)
maybe (Value (ReaderT singleValueFn)) =
Value (ReaderT (traverse (singleValueFn . pure) . listToMaybe))
bool :: Value Bool
bool =
fromMaybe False <$> maybe (parser B.lenientParser)