module Raaz.Core.Encode
       ( -- * Encoding of binary data.
         -- $encodable$
         Encodable(..)
       , Format(..)
       , encode, decode, translate, unsafeDecode
       -- ** The base 16 encoding format
       , Base16
       , fromBase16, showBase16
       -- ** Other binary formats.
       , Base64
       ) where

import Raaz.Core.Encode.Internal
import Raaz.Core.Encode.Base16
import Raaz.Core.Encode.Base64

-- $encodable$
--
-- Often one wants to represent cryptographic hashes, secret keys or
-- just binary data into various enocoding formats like base64,
-- hexadecimal etc. This module gives a generic interface for all such
-- operations. There are two main classes that capture the essence of
-- encoding.
--
-- [`Format`] Each encoding supported by this module is an instance of
--     this class. For printing and for easy inclusion in source code
--     appropriate instances of `Show` and `Data.String.IsString` is
--     provided for these types.
--
-- [`Encodable`] Instances of this class are those that can be encoded
--    into any of the available formats. Actual encoding and decoding
--    of elements of this class can be done by the combinators
--    `encode` and `decode`
--
-- The raaz library exposes many instances of `Format` which are all
-- some form of encoding of binary data.
--

-- | Encode in a given format.
encode :: (Encodable a, Format fmt) => a -> fmt
encode = encodeByteString . toByteString

-- | Decode from a given format. It results in Nothing if there is a
-- parse error.
decode :: (Format fmt, Encodable a) => fmt -> Maybe a
decode = fromByteString . decodeFormat

-- | The unsafe version of `decode`.
unsafeDecode :: (Format fmt, Encodable a) => fmt -> a
unsafeDecode = unsafeFromByteString . decodeFormat

-- | Translate from one format to another.
translate :: (Format fmt1, Format fmt2) => fmt1 -> fmt2
translate = encodeByteString . decodeFormat