2018-07-20 10:22:46 +03:00
|
|
|
module Data.TByteString
|
2021-09-24 01:56:37 +03:00
|
|
|
( TByteString,
|
|
|
|
fromText,
|
|
|
|
fromBS,
|
|
|
|
fromLBS,
|
2022-01-19 07:46:42 +03:00
|
|
|
toLBS,
|
2021-09-24 01:56:37 +03:00
|
|
|
)
|
|
|
|
where
|
|
|
|
|
|
|
|
import Data.Aeson qualified as J
|
|
|
|
import Data.Bool (bool)
|
|
|
|
import Data.ByteString qualified as B
|
|
|
|
import Data.ByteString.Base64 qualified as B64
|
|
|
|
import Data.ByteString.Lazy qualified as BL
|
|
|
|
import Data.String
|
|
|
|
import Data.Text qualified as T
|
|
|
|
import Data.Text.Encoding qualified as TE
|
|
|
|
import Prelude
|
2018-07-20 10:22:46 +03:00
|
|
|
|
2020-03-05 20:59:26 +03:00
|
|
|
-- | A JSON-serializable type for either text or raw binary data, encoded with base-64.
|
2018-07-20 10:22:46 +03:00
|
|
|
newtype TByteString
|
|
|
|
= TByteString (Bool, T.Text)
|
|
|
|
deriving (Show, Eq)
|
|
|
|
|
|
|
|
instance J.ToJSON TByteString where
|
|
|
|
toJSON (TByteString (isBase64, t)) =
|
|
|
|
bool (J.toJSON t) (J.toJSON ["Base64", t]) isBase64
|
|
|
|
|
2020-03-05 20:59:26 +03:00
|
|
|
instance IsString TByteString where
|
|
|
|
fromString = fromText . T.pack
|
|
|
|
|
2018-07-20 10:22:46 +03:00
|
|
|
fromText :: T.Text -> TByteString
|
|
|
|
fromText t = TByteString (False, t)
|
|
|
|
|
|
|
|
fromBS :: B.ByteString -> TByteString
|
|
|
|
fromBS bs =
|
|
|
|
TByteString $
|
2021-09-24 01:56:37 +03:00
|
|
|
-- if the bs in not utf-8 encoded, encode it to Base64
|
|
|
|
case TE.decodeUtf8' bs of
|
|
|
|
Left _ -> (True, TE.decodeUtf8 $ B64.encode bs)
|
|
|
|
Right t -> (False, t)
|
2018-07-20 10:22:46 +03:00
|
|
|
|
|
|
|
fromLBS :: BL.ByteString -> TByteString
|
|
|
|
fromLBS =
|
|
|
|
fromBS . BL.toStrict
|
2022-01-19 07:46:42 +03:00
|
|
|
|
|
|
|
toBS :: TByteString -> Maybe B.ByteString
|
|
|
|
toBS (TByteString (p, txt)) =
|
|
|
|
case p of
|
|
|
|
-- Text is encoded in Base64
|
|
|
|
True -> case B64.decode $ TE.encodeUtf8 txt of
|
|
|
|
Left _ -> Nothing
|
|
|
|
Right bs -> Just bs
|
|
|
|
-- Text is not encoded in Base64
|
|
|
|
False -> Just $ TE.encodeUtf8 txt
|
|
|
|
|
|
|
|
toLBS :: TByteString -> Maybe BL.ByteString
|
|
|
|
toLBS = fmap BL.fromStrict . toBS
|