{-# LANGUAGE OverloadedStrings #-}
module Data.Readable
( Readable(..)
) where
import Control.Monad
import Data.ByteString.Char8 (ByteString)
import Data.Int
import Data.Text (Text)
import qualified Data.Text as T
import Data.Text.Encoding
import Data.Text.Read
import Data.Word
class Readable a where
fromText :: MonadPlus m => Text -> m a
fromBS :: MonadPlus m => ByteString -> m a
fromBS = Text -> m a
forall a (m :: * -> *). (Readable a, MonadPlus m) => Text -> m a
fromText (Text -> m a) -> (ByteString -> m Text) -> ByteString -> m a
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Either UnicodeException Text -> m Text
forall (m :: * -> *) a b. MonadPlus m => Either a b -> m b
hushPlus (Either UnicodeException Text -> m Text)
-> (ByteString -> Either UnicodeException Text)
-> ByteString
-> m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either UnicodeException Text
decodeUtf8'
hushPlus :: MonadPlus m => Either a b -> m b
hushPlus :: Either a b -> m b
hushPlus (Left _) = m b
forall (m :: * -> *) a. MonadPlus m => m a
mzero
hushPlus (Right b :: b
b) = b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
b
checkComplete :: MonadPlus m => (t, Text) -> m t
checkComplete :: (t, Text) -> m t
checkComplete (a :: t
a,rest :: Text
rest)
| Text -> Bool
T.null Text
rest = t -> m t
forall (m :: * -> *) a. Monad m => a -> m a
return t
a
| Bool
otherwise = m t
forall (m :: * -> *) a. MonadPlus m => m a
mzero
instance Readable ByteString where
fromText :: Text -> m ByteString
fromText = ByteString -> m ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> m ByteString)
-> (Text -> ByteString) -> Text -> m ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8
fromBS :: ByteString -> m ByteString
fromBS = ByteString -> m ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return
instance Readable Text where
fromText :: Text -> m Text
fromText = Text -> m Text
forall (m :: * -> *) a. Monad m => a -> m a
return
instance Readable Int where
fromText :: Text -> m Int
fromText = (String -> m Int)
-> ((Int, Text) -> m Int) -> Either String (Int, Text) -> m Int
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Int -> String -> m Int
forall a b. a -> b -> a
const m Int
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Int, Text) -> m Int
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Int, Text) -> m Int)
-> (Text -> Either String (Int, Text)) -> Text -> m Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Either String (Int, Text))
-> Text -> Either String (Int, Text)
forall a. Num a => Reader a -> Reader a
signed Text -> Either String (Int, Text)
forall a. Integral a => Reader a
decimal
instance Readable Integer where
fromText :: Text -> m Integer
fromText = (String -> m Integer)
-> ((Integer, Text) -> m Integer)
-> Either String (Integer, Text)
-> m Integer
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Integer -> String -> m Integer
forall a b. a -> b -> a
const m Integer
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Integer, Text) -> m Integer
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Integer, Text) -> m Integer)
-> (Text -> Either String (Integer, Text)) -> Text -> m Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Either String (Integer, Text))
-> Text -> Either String (Integer, Text)
forall a. Num a => Reader a -> Reader a
signed Text -> Either String (Integer, Text)
forall a. Integral a => Reader a
decimal
instance Readable Float where
fromText :: Text -> m Float
fromText = (String -> m Float)
-> ((Float, Text) -> m Float)
-> Either String (Float, Text)
-> m Float
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Float -> String -> m Float
forall a b. a -> b -> a
const m Float
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Float, Text) -> m Float
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Float, Text) -> m Float)
-> (Text -> Either String (Float, Text)) -> Text -> m Float
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either String (Float, Text)
forall a. Fractional a => Reader a
rational
instance Readable Double where
fromText :: Text -> m Double
fromText = (String -> m Double)
-> ((Double, Text) -> m Double)
-> Either String (Double, Text)
-> m Double
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Double -> String -> m Double
forall a b. a -> b -> a
const m Double
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Double, Text) -> m Double
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Double, Text) -> m Double)
-> (Text -> Either String (Double, Text)) -> Text -> m Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either String (Double, Text)
double
instance Readable Bool where
fromText :: Text -> m Bool
fromText t :: Text
t = case Text -> Text
T.toLower Text
t of
"1" -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
"0" -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
"t" -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
"f" -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
"true" -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
"false" -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
"y" -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
"n" -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
"yes" -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
"no" -> Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
_ -> m Bool
forall (m :: * -> *) a. MonadPlus m => m a
mzero
instance Readable Int8 where
fromText :: Text -> m Int8
fromText = (String -> m Int8)
-> ((Int8, Text) -> m Int8) -> Either String (Int8, Text) -> m Int8
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Int8 -> String -> m Int8
forall a b. a -> b -> a
const m Int8
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Int8, Text) -> m Int8
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Int8, Text) -> m Int8)
-> (Text -> Either String (Int8, Text)) -> Text -> m Int8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Either String (Int8, Text))
-> Text -> Either String (Int8, Text)
forall a. Num a => Reader a -> Reader a
signed Text -> Either String (Int8, Text)
forall a. Integral a => Reader a
decimal
instance Readable Int16 where
fromText :: Text -> m Int16
fromText = (String -> m Int16)
-> ((Int16, Text) -> m Int16)
-> Either String (Int16, Text)
-> m Int16
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Int16 -> String -> m Int16
forall a b. a -> b -> a
const m Int16
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Int16, Text) -> m Int16
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Int16, Text) -> m Int16)
-> (Text -> Either String (Int16, Text)) -> Text -> m Int16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Either String (Int16, Text))
-> Text -> Either String (Int16, Text)
forall a. Num a => Reader a -> Reader a
signed Text -> Either String (Int16, Text)
forall a. Integral a => Reader a
decimal
instance Readable Int32 where
fromText :: Text -> m Int32
fromText = (String -> m Int32)
-> ((Int32, Text) -> m Int32)
-> Either String (Int32, Text)
-> m Int32
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Int32 -> String -> m Int32
forall a b. a -> b -> a
const m Int32
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Int32, Text) -> m Int32
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Int32, Text) -> m Int32)
-> (Text -> Either String (Int32, Text)) -> Text -> m Int32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Either String (Int32, Text))
-> Text -> Either String (Int32, Text)
forall a. Num a => Reader a -> Reader a
signed Text -> Either String (Int32, Text)
forall a. Integral a => Reader a
decimal
instance Readable Int64 where
fromText :: Text -> m Int64
fromText = (String -> m Int64)
-> ((Int64, Text) -> m Int64)
-> Either String (Int64, Text)
-> m Int64
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Int64 -> String -> m Int64
forall a b. a -> b -> a
const m Int64
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Int64, Text) -> m Int64
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Int64, Text) -> m Int64)
-> (Text -> Either String (Int64, Text)) -> Text -> m Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Either String (Int64, Text))
-> Text -> Either String (Int64, Text)
forall a. Num a => Reader a -> Reader a
signed Text -> Either String (Int64, Text)
forall a. Integral a => Reader a
decimal
instance Readable Word8 where
fromText :: Text -> m Word8
fromText = (String -> m Word8)
-> ((Word8, Text) -> m Word8)
-> Either String (Word8, Text)
-> m Word8
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Word8 -> String -> m Word8
forall a b. a -> b -> a
const m Word8
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Word8, Text) -> m Word8
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Word8, Text) -> m Word8)
-> (Text -> Either String (Word8, Text)) -> Text -> m Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either String (Word8, Text)
forall a. Integral a => Reader a
decimal
instance Readable Word16 where
fromText :: Text -> m Word16
fromText = (String -> m Word16)
-> ((Word16, Text) -> m Word16)
-> Either String (Word16, Text)
-> m Word16
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Word16 -> String -> m Word16
forall a b. a -> b -> a
const m Word16
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Word16, Text) -> m Word16
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Word16, Text) -> m Word16)
-> (Text -> Either String (Word16, Text)) -> Text -> m Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either String (Word16, Text)
forall a. Integral a => Reader a
decimal
instance Readable Word32 where
fromText :: Text -> m Word32
fromText = (String -> m Word32)
-> ((Word32, Text) -> m Word32)
-> Either String (Word32, Text)
-> m Word32
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Word32 -> String -> m Word32
forall a b. a -> b -> a
const m Word32
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Word32, Text) -> m Word32
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Word32, Text) -> m Word32)
-> (Text -> Either String (Word32, Text)) -> Text -> m Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either String (Word32, Text)
forall a. Integral a => Reader a
decimal
instance Readable Word64 where
fromText :: Text -> m Word64
fromText = (String -> m Word64)
-> ((Word64, Text) -> m Word64)
-> Either String (Word64, Text)
-> m Word64
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (m Word64 -> String -> m Word64
forall a b. a -> b -> a
const m Word64
forall (m :: * -> *) a. MonadPlus m => m a
mzero) (Word64, Text) -> m Word64
forall (m :: * -> *) t. MonadPlus m => (t, Text) -> m t
checkComplete (Either String (Word64, Text) -> m Word64)
-> (Text -> Either String (Word64, Text)) -> Text -> m Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either String (Word64, Text)
forall a. Integral a => Reader a
decimal