1module Hackage.Security.Util.Base64 (
2    Base64 -- opaque
3  , fromByteString
4  , toByteString
5  ) where
6
7import Data.ByteString (ByteString)
8import qualified Data.ByteString.Char8  as C8  -- only called on B64-enc strings
9import qualified Data.ByteString.Base64 as B64
10
11import Hackage.Security.Util.JSON
12
13-- | Simple wrapper around bytestring with ToJSON and FromJSON instances that
14-- use base64 encoding.
15newtype Base64 = Base64 ByteString
16
17fromByteString :: ByteString -> Base64
18fromByteString = Base64
19
20toByteString :: Base64 -> ByteString
21toByteString (Base64 bs) = bs
22
23instance Monad m => ToJSON m Base64 where
24  toJSON (Base64 bs) = toJSON (C8.unpack (B64.encode bs))
25
26instance ReportSchemaErrors m => FromJSON m Base64 where
27  fromJSON val = do
28    str <- fromJSON val
29    case B64.decode (C8.pack str) of
30      Left _err -> expected "base-64 encoded string" Nothing
31      Right bs  -> return $ Base64 bs
32