module Amazonka.Data.Text
( Text,
FromText (..),
ToText (..),
toTextCI,
showText,
)
where
import qualified Amazonka.Bytes as Bytes
import qualified Amazonka.Crypto as Crypto
import Amazonka.Prelude
import qualified Data.Attoparsec.Text as A
import qualified Data.ByteString.Char8 as BS8
import qualified Data.CaseInsensitive as CI
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import qualified Data.Text.Lazy as LText
import qualified Data.Text.Lazy.Builder as Build
import qualified Data.Text.Lazy.Builder.Int as Build
import qualified Data.Text.Lazy.Builder.Scientific as Build
import qualified Network.HTTP.Types as HTTP
import qualified Numeric
class FromText a where
fromText :: Text -> Either String a
instance FromText Text where
fromText :: Text -> Either String Text
fromText = Text -> Either String Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure
instance FromText String where
fromText :: Text -> Either String String
fromText = String -> Either String String
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Either String String)
-> (Text -> String) -> Text -> Either String String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
Text.unpack
instance FromText ByteString where
fromText :: Text -> Either String ByteString
fromText = ByteString -> Either String ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> Either String ByteString)
-> (Text -> ByteString) -> Text -> Either String ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
Text.encodeUtf8
instance (CI.FoldCase a, FromText a) => FromText (CI a) where
fromText :: Text -> Either String (CI a)
fromText = (a -> CI a) -> Either String a -> Either String (CI a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> CI a
forall s. FoldCase s => s -> CI s
CI.mk (Either String a -> Either String (CI a))
-> (Text -> Either String a) -> Text -> Either String (CI a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either String a
forall a. FromText a => Text -> Either String a
fromText
instance FromText Char where
fromText :: Text -> Either String Char
fromText = Parser Char -> Text -> Either String Char
forall a. Parser a -> Text -> Either String a
A.parseOnly (Parser Char
A.anyChar Parser Char -> Parser Text () -> Parser Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
forall t. Chunk t => Parser t ()
A.endOfInput)
instance FromText Int where
fromText :: Text -> Either String Int
fromText = Parser Int -> Text -> Either String Int
forall a. Parser a -> Text -> Either String a
A.parseOnly (Parser Int -> Parser Int
forall a. Num a => Parser a -> Parser a
A.signed Parser Int
forall a. Integral a => Parser a
A.decimal Parser Int -> Parser Text () -> Parser Int
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
forall t. Chunk t => Parser t ()
A.endOfInput)
instance FromText Int64 where
fromText :: Text -> Either String Int64
fromText = Parser Int64 -> Text -> Either String Int64
forall a. Parser a -> Text -> Either String a
A.parseOnly (Parser Int64 -> Parser Int64
forall a. Num a => Parser a -> Parser a
A.signed Parser Int64
forall a. Integral a => Parser a
A.decimal Parser Int64 -> Parser Text () -> Parser Int64
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
forall t. Chunk t => Parser t ()
A.endOfInput)
instance FromText Integer where
fromText :: Text -> Either String Integer
fromText = Parser Integer -> Text -> Either String Integer
forall a. Parser a -> Text -> Either String a
A.parseOnly (Parser Integer -> Parser Integer
forall a. Num a => Parser a -> Parser a
A.signed Parser Integer
forall a. Integral a => Parser a
A.decimal Parser Integer -> Parser Text () -> Parser Integer
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
forall t. Chunk t => Parser t ()
A.endOfInput)
instance FromText Scientific where
fromText :: Text -> Either String Scientific
fromText = Parser Scientific -> Text -> Either String Scientific
forall a. Parser a -> Text -> Either String a
A.parseOnly (Parser Scientific -> Parser Scientific
forall a. Num a => Parser a -> Parser a
A.signed Parser Scientific
A.scientific Parser Scientific -> Parser Text () -> Parser Scientific
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
forall t. Chunk t => Parser t ()
A.endOfInput)
instance FromText Natural where
fromText :: Text -> Either String Natural
fromText = Parser Natural -> Text -> Either String Natural
forall a. Parser a -> Text -> Either String a
A.parseOnly (Parser Natural
forall a. Integral a => Parser a
A.decimal Parser Natural -> Parser Text () -> Parser Natural
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
forall t. Chunk t => Parser t ()
A.endOfInput)
instance FromText Double where
fromText :: Text -> Either String Double
fromText = Parser Double -> Text -> Either String Double
forall a. Parser a -> Text -> Either String a
A.parseOnly (Parser Double -> Parser Double
forall a. Num a => Parser a -> Parser a
A.signed Parser Double
forall a. Fractional a => Parser a
A.rational Parser Double -> Parser Text () -> Parser Double
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
forall t. Chunk t => Parser t ()
A.endOfInput)
instance FromText Bool where
fromText :: Text -> Either String Bool
fromText Text
text =
case Text -> CI Text
forall s. FoldCase s => s -> CI s
CI.mk Text
text of
CI Text
"true" -> Bool -> Either String Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
CI Text
"false" -> Bool -> Either String Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False
CI Text
other -> String -> Either String Bool
forall a b. a -> Either a b
Left (String
"Failure parsing Bool from " String -> String -> String
forall a. [a] -> [a] -> [a]
++ CI Text -> String
forall a. Show a => a -> String
show CI Text
other String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
".")
instance FromText HTTP.StdMethod where
fromText :: Text -> Either String StdMethod
fromText Text
text =
case ByteString -> Either ByteString StdMethod
HTTP.parseMethod (Text -> ByteString
Text.encodeUtf8 Text
text) of
Left ByteString
err -> String -> Either String StdMethod
forall a b. a -> Either a b
Left (ByteString -> String
BS8.unpack ByteString
err)
Right StdMethod
ok -> StdMethod -> Either String StdMethod
forall (f :: * -> *) a. Applicative f => a -> f a
pure StdMethod
ok
showText :: ToText a => a -> String
showText :: a -> String
showText = Text -> String
Text.unpack (Text -> String) -> (a -> Text) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
forall a. ToText a => a -> Text
toText
class ToText a where
toText :: a -> Text
instance ToText a => ToText (CI a) where
toText :: CI a -> Text
toText = a -> Text
forall a. ToText a => a -> Text
toText (a -> Text) -> (CI a -> a) -> CI a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CI a -> a
forall s. CI s -> s
CI.original
instance ToText Text where
toText :: Text -> Text
toText = Text -> Text
forall a. a -> a
id
instance ToText ByteString where
toText :: ByteString -> Text
toText = ByteString -> Text
Text.decodeUtf8
instance ToText Char where
toText :: Char -> Text
toText = Char -> Text
Text.singleton
instance ToText String where
toText :: String -> Text
toText = String -> Text
Text.pack
instance ToText Int where
toText :: Int -> Text
toText = TextBuilder -> Text
shortText (TextBuilder -> Text) -> (Int -> TextBuilder) -> Int -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> TextBuilder
forall a. Integral a => a -> TextBuilder
Build.decimal
instance ToText Int64 where
toText :: Int64 -> Text
toText = TextBuilder -> Text
shortText (TextBuilder -> Text) -> (Int64 -> TextBuilder) -> Int64 -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> TextBuilder
forall a. Integral a => a -> TextBuilder
Build.decimal
instance ToText Integer where
toText :: Integer -> Text
toText = TextBuilder -> Text
shortText (TextBuilder -> Text)
-> (Integer -> TextBuilder) -> Integer -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> TextBuilder
forall a. Integral a => a -> TextBuilder
Build.decimal
instance ToText Natural where
toText :: Natural -> Text
toText = TextBuilder -> Text
shortText (TextBuilder -> Text)
-> (Natural -> TextBuilder) -> Natural -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> TextBuilder
forall a. Integral a => a -> TextBuilder
Build.decimal
instance ToText Scientific where
toText :: Scientific -> Text
toText = TextBuilder -> Text
shortText (TextBuilder -> Text)
-> (Scientific -> TextBuilder) -> Scientific -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scientific -> TextBuilder
Build.scientificBuilder
instance ToText Double where
toText :: Double -> Text
toText = String -> Text
forall a. ToText a => a -> Text
toText (String -> Text) -> (Double -> String) -> Double -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
"") ((String -> String) -> String)
-> (Double -> String -> String) -> Double -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Int -> Double -> String -> String
forall a. RealFloat a => Maybe Int -> a -> String -> String
Numeric.showFFloat Maybe Int
forall a. Maybe a
Nothing
instance ToText HTTP.StdMethod where
toText :: StdMethod -> Text
toText = ByteString -> Text
forall a. ToText a => a -> Text
toText (ByteString -> Text)
-> (StdMethod -> ByteString) -> StdMethod -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StdMethod -> ByteString
HTTP.renderStdMethod
instance ToText (Crypto.Digest a) where
toText :: Digest a -> Text
toText = ByteString -> Text
forall a. ToText a => a -> Text
toText (ByteString -> Text)
-> (Digest a -> ByteString) -> Digest a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Digest a -> ByteString
forall a. ByteArrayAccess a => a -> ByteString
Bytes.encodeBase16
instance ToText Bool where
toText :: Bool -> Text
toText Bool
True = Text
"true"
toText Bool
False = Text
"false"
shortText :: TextBuilder -> Text
shortText :: TextBuilder -> Text
shortText = Text -> Text
LText.toStrict (Text -> Text) -> (TextBuilder -> Text) -> TextBuilder -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> TextBuilder -> Text
Build.toLazyTextWith Int
32
toTextCI :: ToText a => a -> CI Text
toTextCI :: a -> CI Text
toTextCI = Text -> CI Text
forall s. FoldCase s => s -> CI s
CI.mk (Text -> CI Text) -> (a -> Text) -> a -> CI Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
forall a. ToText a => a -> Text
toText