module Codec.Xlsx.Parser.Internal.Util ( boolean , eitherBoolean , decimal , eitherDecimal , rational , eitherRational ) where import Data.Text (Text) import Control.Monad.Fail (MonadFail) import qualified Data.Text as T import qualified Data.Text.Read as T import qualified Control.Monad.Fail as F decimal :: (MonadFail m, Integral a) => Text -> m a decimal = fromEither . eitherDecimal eitherDecimal :: (Integral a) => Text -> Either String a eitherDecimal t = case T.signed T.decimal t of Right (d, leftover) | T.null leftover -> Right d _ -> Left $ "invalid decimal: " ++ show t rational :: (MonadFail m) => Text -> m Double rational = fromEither . eitherRational eitherRational :: Text -> Either String Double eitherRational t = case T.signed T.rational t of Right (r, leftover) | T.null leftover -> Right r _ -> Left $ "invalid rational: " ++ show t boolean :: (MonadFail m) => Text -> m Bool boolean = fromEither . eitherBoolean eitherBoolean :: Text -> Either String Bool eitherBoolean t = case T.unpack $ T.strip t of "true" -> Right True "false" -> Right False _ -> Left $ "invalid boolean: " ++ show t fromEither :: (MonadFail m) => Either String b -> m b fromEither (Left a) = F.fail a fromEither (Right b) = return b