module Serokell.Util.Base64
( encode
, decode
, encodeUrl
, decodeUrl
, formatBase64
, base64F
, JsonByteString (..)
, JsonByteStringDeprecated (..)
) where
import Control.Monad ((>=>))
import Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON))
import qualified Data.ByteString as BS
import qualified Data.ByteString.Base64 as B64
import qualified Data.ByteString.Base64.URL as B64url
import Data.Either.Combinators (mapLeft)
import qualified Data.Text as T
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
import Data.Text.Lazy.Builder (Builder, fromText)
import Formatting (Format, later)
encode :: BS.ByteString -> T.Text
encode = decodeUtf8 . B64.encode
decode :: T.Text -> Either T.Text BS.ByteString
decode = mapLeft T.pack . B64.decode . encodeUtf8
encodeUrl :: BS.ByteString -> T.Text
encodeUrl = decodeUtf8 . B64url.encode
decodeUrl :: T.Text -> Either T.Text BS.ByteString
decodeUrl = mapLeft T.pack . B64url.decode . encodeUtf8
formatBase64 :: BS.ByteString -> Builder
formatBase64 = fromText . encode
base64F :: Format r (BS.ByteString -> r)
base64F = later formatBase64
newtype JsonByteString = JsonByteString
{ getJsonByteString :: BS.ByteString
}
instance ToJSON JsonByteString where
toJSON = toJSON . encode . getJsonByteString
instance FromJSON JsonByteString where
parseJSON =
parseJSON >=>
either (fail . T.unpack) (pure . JsonByteString) . decode
newtype JsonByteStringDeprecated = JsonByteStringDeprecated
{ getJsonByteStringDeprecated :: BS.ByteString
}
instance ToJSON JsonByteStringDeprecated where
toJSON = toJSON . encodeUrl . getJsonByteStringDeprecated
instance FromJSON JsonByteStringDeprecated where
parseJSON =
parseJSON >=>
either (fail . T.unpack) (pure . JsonByteStringDeprecated) . decodeUrl