143 lines
3.3 KiB
Haskell
143 lines
3.3 KiB
Haskell
{-# LANGUAGE FlexibleInstances #-}
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
{-# LANGUAGE TypeSynonymInstances #-}
|
|
module Servant.Common.Text
|
|
( FromText(..)
|
|
, ToText(..)
|
|
) where
|
|
|
|
import Control.Applicative ((<$>))
|
|
import Data.Int (Int16, Int32, Int64, Int8)
|
|
import Data.String.Conversions (cs)
|
|
import Data.Text (Text)
|
|
import Data.Text.Read (Reader, decimal, rational, signed)
|
|
import Data.Word (Word, Word16, Word32, Word64, Word8)
|
|
|
|
-- | For getting values from url captures and query string parameters
|
|
-- Instances should obey:
|
|
-- > fromText (toText a) == Just a
|
|
class FromText a where
|
|
fromText :: Text -> Maybe a
|
|
|
|
-- | For putting values in paths and query string parameters
|
|
-- Instances should obey:
|
|
-- > fromText (toText a) == Just a
|
|
class ToText a where
|
|
toText :: a -> Text
|
|
|
|
instance FromText Text where
|
|
fromText = Just
|
|
|
|
instance ToText Text where
|
|
toText = id
|
|
|
|
instance FromText String where
|
|
fromText = Just . cs
|
|
|
|
instance ToText String where
|
|
toText = cs
|
|
|
|
-- |
|
|
-- >>> fromText ("true"::Text) :: Maybe Bool
|
|
-- Just True
|
|
-- >>> fromText ("false"::Text) :: Maybe Bool
|
|
-- Just False
|
|
-- >>> fromText ("anything else"::Text) :: Maybe Bool
|
|
-- Nothing
|
|
instance FromText Bool where
|
|
fromText "true" = Just True
|
|
fromText "false" = Just False
|
|
fromText _ = Nothing
|
|
|
|
-- |
|
|
-- >>> toText True
|
|
-- "true"
|
|
-- >>> toText False
|
|
-- "false"
|
|
instance ToText Bool where
|
|
toText True = "true"
|
|
toText False = "false"
|
|
|
|
instance FromText Int where
|
|
fromText = runReader (signed decimal)
|
|
|
|
instance ToText Int where
|
|
toText = cs . show
|
|
|
|
instance FromText Int8 where
|
|
fromText = runReader (signed decimal)
|
|
|
|
instance ToText Int8 where
|
|
toText = cs . show
|
|
|
|
instance FromText Int16 where
|
|
fromText = runReader (signed decimal)
|
|
|
|
instance ToText Int16 where
|
|
toText = cs . show
|
|
|
|
instance FromText Int32 where
|
|
fromText = runReader (signed decimal)
|
|
|
|
instance ToText Int32 where
|
|
toText = cs . show
|
|
|
|
instance FromText Int64 where
|
|
fromText = runReader (signed decimal)
|
|
|
|
instance ToText Int64 where
|
|
toText = cs . show
|
|
|
|
instance FromText Word where
|
|
fromText = runReader decimal
|
|
|
|
instance ToText Word where
|
|
toText = cs . show
|
|
|
|
instance FromText Word8 where
|
|
fromText = runReader decimal
|
|
|
|
instance ToText Word8 where
|
|
toText = cs . show
|
|
|
|
instance FromText Word16 where
|
|
fromText = runReader decimal
|
|
|
|
instance ToText Word16 where
|
|
toText = cs . show
|
|
|
|
instance FromText Word32 where
|
|
fromText = runReader decimal
|
|
|
|
instance ToText Word32 where
|
|
toText = cs . show
|
|
|
|
instance FromText Word64 where
|
|
fromText = runReader decimal
|
|
|
|
instance ToText Word64 where
|
|
toText = cs . show
|
|
|
|
instance FromText Integer where
|
|
fromText = runReader (signed decimal)
|
|
|
|
instance ToText Integer where
|
|
toText = cs . show
|
|
|
|
instance FromText Double where
|
|
fromText x = fromRational <$> runReader rational x
|
|
|
|
instance ToText Double where
|
|
toText = cs . show
|
|
|
|
instance FromText Float where
|
|
-- Double is more practically accurate due to weird rounding when using
|
|
-- rational. We convert to double and then convert to Float.
|
|
fromText x = fromRational <$> runReader rational x
|
|
|
|
instance ToText Float where
|
|
toText = cs . show
|
|
|
|
runReader :: Reader a -> Text -> Maybe a
|
|
runReader reader t = either (const Nothing) (Just . fst) $ reader t
|