{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.ByteArray.Base64String where
import Data.Aeson (FromJSON (..), ToJSON (..),
Value (..), withText)
import Data.ByteArray (ByteArray, ByteArrayAccess, convert)
import Data.ByteArray.Encoding (Base (Base64), convertFromBase,
convertToBase)
import Data.ByteString (ByteString)
import Data.Monoid (Monoid)
import Data.Semigroup (Semigroup)
import Data.String (IsString (..))
import Data.Text (Text)
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
newtype Base64String = Base64String { unBase64String :: ByteString }
deriving (Eq, Ord, Semigroup, Monoid, ByteArrayAccess, ByteArray)
instance Show Base64String where
show = ("Base64String " ++) . show . format
instance IsString Base64String where
fromString = base64String' . fromString
where
base64String' :: ByteString -> Base64String
base64String' = either error id . base64String
instance FromJSON Base64String where
parseJSON Null = pure (fromBytes ("" :: ByteString))
parseJSON v = withText "Base64String" (either fail pure . base64String . encodeUtf8) v
instance ToJSON Base64String where
toJSON = String . toText
base64String :: ByteArray ba => ba -> Either String Base64String
base64String bs = Base64String <$> convertFromBase Base64 bs
fromBytes :: ByteArrayAccess ba => ba -> Base64String
fromBytes = Base64String . convert
toBytes :: ByteArray ba => Base64String -> ba
toBytes = convert . unBase64String
toText :: Base64String -> Text
toText = decodeUtf8 . convertToBase Base64 . unBase64String
format :: Base64String -> Text
format = toText