module ClickHaskell.Primitive.TString where
import ClickHaskell.Primitive.Serialization
import Control.DeepSeq (NFData)
import Data.Binary.Get
import Data.ByteString as BS (ByteString, length)
import Data.ByteString.Builder
import Data.ByteString.Char8 as BS8 (pack, unpack, concatMap, singleton)
import Data.ByteString.Lazy (toStrict)
import Data.String (IsString (..))
import Prelude hiding (liftA2)
newtype ChString = MkChString BS.ByteString
deriving newtype (Int -> ChString -> ShowS
[ChString] -> ShowS
ChString -> String
(Int -> ChString -> ShowS)
-> (ChString -> String) -> ([ChString] -> ShowS) -> Show ChString
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ChString -> ShowS
showsPrec :: Int -> ChString -> ShowS
$cshow :: ChString -> String
show :: ChString -> String
$cshowList :: [ChString] -> ShowS
showList :: [ChString] -> ShowS
Show, ChString -> ChString -> Bool
(ChString -> ChString -> Bool)
-> (ChString -> ChString -> Bool) -> Eq ChString
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ChString -> ChString -> Bool
== :: ChString -> ChString -> Bool
$c/= :: ChString -> ChString -> Bool
/= :: ChString -> ChString -> Bool
Eq, String -> ChString
(String -> ChString) -> IsString ChString
forall a. (String -> a) -> IsString a
$cfromString :: String -> ChString
fromString :: String -> ChString
IsString, ChString -> ()
(ChString -> ()) -> NFData ChString
forall a. (a -> ()) -> NFData a
$crnf :: ChString -> ()
rnf :: ChString -> ()
NFData)
instance IsChType ChString where
chTypeName :: String
chTypeName = String
"String"
defaultValueOfTypeName :: ChString
defaultValueOfTypeName = ChString
""
instance Serializable ChString where
serialize :: ProtocolRevision -> ChString -> Builder
serialize ProtocolRevision
rev (MkChString ByteString
str) = (forall chType.
Serializable chType =>
ProtocolRevision -> chType -> Builder
serialize @UVarInt ProtocolRevision
rev (UVarInt -> Builder)
-> (ByteString -> UVarInt) -> ByteString -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> UVarInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> UVarInt) -> (ByteString -> Int) -> ByteString -> UVarInt
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Int
BS.length) ByteString
str Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
byteString ByteString
str
deserialize :: ProtocolRevision -> Get ChString
deserialize ProtocolRevision
rev = do
len <- forall chType.
Serializable chType =>
ProtocolRevision -> Get chType
deserialize @UVarInt ProtocolRevision
rev
MkChString <$> (getByteString . fromIntegral) len
{-# INLINE deserialize #-}
instance ToChType ChString BS.ByteString where
toChType :: ByteString -> ChString
toChType = ByteString -> ChString
MkChString
fromChType :: ChString -> ByteString
fromChType (MkChString ByteString
string) = ByteString
string
instance ToChType ChString Builder where
toChType :: Builder -> ChString
toChType = ByteString -> ChString
MkChString (ByteString -> ChString)
-> (Builder -> ByteString) -> Builder -> ChString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LazyByteString -> ByteString
toStrict (LazyByteString -> ByteString)
-> (Builder -> LazyByteString) -> Builder -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> LazyByteString
toLazyByteString
fromChType :: ChString -> Builder
fromChType (MkChString ByteString
string) = ByteString -> Builder
byteString ByteString
string
instance ToChType ChString String where
toChType :: String -> ChString
toChType = ByteString -> ChString
MkChString (ByteString -> ChString)
-> (String -> ByteString) -> String -> ChString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
BS8.pack
fromChType :: ChString -> String
fromChType (MkChString ByteString
bs)= ByteString -> String
BS8.unpack ByteString
bs
instance ToQueryPart ChString where
toQueryPart :: ChString -> Builder
toQueryPart (MkChString ByteString
string) = Builder
"'" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> ByteString -> Builder
escapeQuery ByteString
string Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"'"
where
escapeQuery :: BS.ByteString -> Builder
escapeQuery :: ByteString -> Builder
escapeQuery = ByteString -> Builder
byteString (ByteString -> Builder)
-> (ByteString -> ByteString) -> ByteString -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> ByteString) -> ByteString -> ByteString
BS8.concatMap (\Char
sym ->
case Char
sym of
Char
'\'' -> ByteString
"\\\'"
Char
'\\' -> ByteString
"\\\\"
Char
_ -> Char -> ByteString
BS8.singleton Char
sym
)