{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}

-- | An alternative to 'Protolude.ConvertText' that includes
-- partial conversions. Not re-exported by 'Protolude'.
module Protolude.Conv (
  StringConv
, strConv
, toS
, toSL
, Leniency (Lenient, Strict)
) where

import Data.ByteString.Char8      as B
import Data.ByteString.Lazy.Char8 as LB
import Data.Text                  as T
import Data.Text.Encoding         as T
import Data.Text.Encoding.Error   as T
import Data.Text.Lazy             as LT
import Data.Text.Lazy.Encoding    as LT

import Protolude.Base
import Data.Eq (Eq)
import Data.Ord (Ord)
import Data.Function ((.), id)
import Data.String (String)
import Control.Applicative (pure)

data Leniency = Lenient | Strict
  deriving (Leniency -> Leniency -> Bool
(Leniency -> Leniency -> Bool)
-> (Leniency -> Leniency -> Bool) -> Eq Leniency
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Leniency -> Leniency -> Bool
$c/= :: Leniency -> Leniency -> Bool
== :: Leniency -> Leniency -> Bool
$c== :: Leniency -> Leniency -> Bool
Eq,Int -> Leniency -> ShowS
[Leniency] -> ShowS
Leniency -> String
(Int -> Leniency -> ShowS)
-> (Leniency -> String) -> ([Leniency] -> ShowS) -> Show Leniency
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Leniency] -> ShowS
$cshowList :: [Leniency] -> ShowS
show :: Leniency -> String
$cshow :: Leniency -> String
showsPrec :: Int -> Leniency -> ShowS
$cshowsPrec :: Int -> Leniency -> ShowS
Show,Eq Leniency
Eq Leniency
-> (Leniency -> Leniency -> Ordering)
-> (Leniency -> Leniency -> Bool)
-> (Leniency -> Leniency -> Bool)
-> (Leniency -> Leniency -> Bool)
-> (Leniency -> Leniency -> Bool)
-> (Leniency -> Leniency -> Leniency)
-> (Leniency -> Leniency -> Leniency)
-> Ord Leniency
Leniency -> Leniency -> Bool
Leniency -> Leniency -> Ordering
Leniency -> Leniency -> Leniency
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Leniency -> Leniency -> Leniency
$cmin :: Leniency -> Leniency -> Leniency
max :: Leniency -> Leniency -> Leniency
$cmax :: Leniency -> Leniency -> Leniency
>= :: Leniency -> Leniency -> Bool
$c>= :: Leniency -> Leniency -> Bool
> :: Leniency -> Leniency -> Bool
$c> :: Leniency -> Leniency -> Bool
<= :: Leniency -> Leniency -> Bool
$c<= :: Leniency -> Leniency -> Bool
< :: Leniency -> Leniency -> Bool
$c< :: Leniency -> Leniency -> Bool
compare :: Leniency -> Leniency -> Ordering
$ccompare :: Leniency -> Leniency -> Ordering
$cp1Ord :: Eq Leniency
Ord,Int -> Leniency
Leniency -> Int
Leniency -> [Leniency]
Leniency -> Leniency
Leniency -> Leniency -> [Leniency]
Leniency -> Leniency -> Leniency -> [Leniency]
(Leniency -> Leniency)
-> (Leniency -> Leniency)
-> (Int -> Leniency)
-> (Leniency -> Int)
-> (Leniency -> [Leniency])
-> (Leniency -> Leniency -> [Leniency])
-> (Leniency -> Leniency -> [Leniency])
-> (Leniency -> Leniency -> Leniency -> [Leniency])
-> Enum Leniency
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Leniency -> Leniency -> Leniency -> [Leniency]
$cenumFromThenTo :: Leniency -> Leniency -> Leniency -> [Leniency]
enumFromTo :: Leniency -> Leniency -> [Leniency]
$cenumFromTo :: Leniency -> Leniency -> [Leniency]
enumFromThen :: Leniency -> Leniency -> [Leniency]
$cenumFromThen :: Leniency -> Leniency -> [Leniency]
enumFrom :: Leniency -> [Leniency]
$cenumFrom :: Leniency -> [Leniency]
fromEnum :: Leniency -> Int
$cfromEnum :: Leniency -> Int
toEnum :: Int -> Leniency
$ctoEnum :: Int -> Leniency
pred :: Leniency -> Leniency
$cpred :: Leniency -> Leniency
succ :: Leniency -> Leniency
$csucc :: Leniency -> Leniency
Enum,Leniency
Leniency -> Leniency -> Bounded Leniency
forall a. a -> a -> Bounded a
maxBound :: Leniency
$cmaxBound :: Leniency
minBound :: Leniency
$cminBound :: Leniency
Bounded)

class StringConv a b where
  strConv :: Leniency -> a -> b

toS :: StringConv a b => a -> b
toS :: a -> b
toS = Leniency -> a -> b
forall a b. StringConv a b => Leniency -> a -> b
strConv Leniency
Strict

toSL :: StringConv a b => a -> b
toSL :: a -> b
toSL = Leniency -> a -> b
forall a b. StringConv a b => Leniency -> a -> b
strConv Leniency
Lenient

instance StringConv String String where strConv :: Leniency -> ShowS
strConv Leniency
_ = ShowS
forall a. a -> a
id
instance StringConv String B.ByteString where strConv :: Leniency -> String -> ByteString
strConv Leniency
_ = String -> ByteString
B.pack
instance StringConv String LB.ByteString where strConv :: Leniency -> String -> ByteString
strConv Leniency
_ = String -> ByteString
LB.pack
instance StringConv String T.Text where strConv :: Leniency -> String -> Text
strConv Leniency
_ = String -> Text
T.pack
instance StringConv String LT.Text where strConv :: Leniency -> String -> Text
strConv Leniency
_ = String -> Text
LT.pack

instance StringConv B.ByteString String where strConv :: Leniency -> ByteString -> String
strConv Leniency
_ = ByteString -> String
B.unpack
instance StringConv B.ByteString B.ByteString where strConv :: Leniency -> ByteString -> ByteString
strConv Leniency
_ = ByteString -> ByteString
forall a. a -> a
id
instance StringConv B.ByteString LB.ByteString where strConv :: Leniency -> ByteString -> ByteString
strConv Leniency
_ = [ByteString] -> ByteString
LB.fromChunks ([ByteString] -> ByteString)
-> (ByteString -> [ByteString]) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
instance StringConv B.ByteString T.Text where strConv :: Leniency -> ByteString -> Text
strConv = Leniency -> ByteString -> Text
decodeUtf8T
instance StringConv B.ByteString LT.Text where strConv :: Leniency -> ByteString -> Text
strConv Leniency
l = Leniency -> ByteString -> Text
forall a b. StringConv a b => Leniency -> a -> b
strConv Leniency
l (ByteString -> Text)
-> (ByteString -> ByteString) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> ByteString
LB.fromChunks ([ByteString] -> ByteString)
-> (ByteString -> [ByteString]) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
forall (f :: * -> *) a. Applicative f => a -> f a
pure

instance StringConv LB.ByteString String where strConv :: Leniency -> ByteString -> String
strConv Leniency
_ = ByteString -> String
LB.unpack
instance StringConv LB.ByteString B.ByteString where strConv :: Leniency -> ByteString -> ByteString
strConv Leniency
_ = [ByteString] -> ByteString
B.concat ([ByteString] -> ByteString)
-> (ByteString -> [ByteString]) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
LB.toChunks
instance StringConv LB.ByteString LB.ByteString where strConv :: Leniency -> ByteString -> ByteString
strConv Leniency
_ = ByteString -> ByteString
forall a. a -> a
id
instance StringConv LB.ByteString T.Text where strConv :: Leniency -> ByteString -> Text
strConv Leniency
l = Leniency -> ByteString -> Text
decodeUtf8T Leniency
l (ByteString -> Text)
-> (ByteString -> ByteString) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Leniency -> ByteString -> ByteString
forall a b. StringConv a b => Leniency -> a -> b
strConv Leniency
l
instance StringConv LB.ByteString LT.Text where strConv :: Leniency -> ByteString -> Text
strConv = Leniency -> ByteString -> Text
decodeUtf8LT

instance StringConv T.Text String where strConv :: Leniency -> Text -> String
strConv Leniency
_ = Text -> String
T.unpack
instance StringConv T.Text B.ByteString where strConv :: Leniency -> Text -> ByteString
strConv Leniency
_ = Text -> ByteString
T.encodeUtf8
instance StringConv T.Text LB.ByteString where strConv :: Leniency -> Text -> ByteString
strConv Leniency
l = Leniency -> ByteString -> ByteString
forall a b. StringConv a b => Leniency -> a -> b
strConv Leniency
l (ByteString -> ByteString)
-> (Text -> ByteString) -> Text -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8
instance StringConv T.Text LT.Text where strConv :: Leniency -> Text -> Text
strConv Leniency
_ = Text -> Text
LT.fromStrict
instance StringConv T.Text T.Text where strConv :: Leniency -> Text -> Text
strConv Leniency
_ = Text -> Text
forall a. a -> a
id

instance StringConv LT.Text String where strConv :: Leniency -> Text -> String
strConv Leniency
_ = Text -> String
LT.unpack
instance StringConv LT.Text T.Text where strConv :: Leniency -> Text -> Text
strConv Leniency
_ = Text -> Text
LT.toStrict
instance StringConv LT.Text LT.Text where strConv :: Leniency -> Text -> Text
strConv Leniency
_ = Text -> Text
forall a. a -> a
id
instance StringConv LT.Text LB.ByteString where strConv :: Leniency -> Text -> ByteString
strConv Leniency
_ = Text -> ByteString
LT.encodeUtf8
instance StringConv LT.Text B.ByteString where strConv :: Leniency -> Text -> ByteString
strConv Leniency
l = Leniency -> ByteString -> ByteString
forall a b. StringConv a b => Leniency -> a -> b
strConv Leniency
l (ByteString -> ByteString)
-> (Text -> ByteString) -> Text -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
LT.encodeUtf8

decodeUtf8T :: Leniency -> B.ByteString -> T.Text
decodeUtf8T :: Leniency -> ByteString -> Text
decodeUtf8T Leniency
Lenient = OnDecodeError -> ByteString -> Text
T.decodeUtf8With OnDecodeError
T.lenientDecode
decodeUtf8T Leniency
Strict = OnDecodeError -> ByteString -> Text
T.decodeUtf8With OnDecodeError
T.strictDecode

decodeUtf8LT :: Leniency -> LB.ByteString -> LT.Text
decodeUtf8LT :: Leniency -> ByteString -> Text
decodeUtf8LT Leniency
Lenient = OnDecodeError -> ByteString -> Text
LT.decodeUtf8With OnDecodeError
T.lenientDecode
decodeUtf8LT Leniency
Strict = OnDecodeError -> ByteString -> Text
LT.decodeUtf8With OnDecodeError
T.strictDecode