{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Distribution.Types.AbiHash
  ( AbiHash, unAbiHash, mkAbiHash
  ) where

import Prelude ()
import Distribution.Compat.Prelude
import Distribution.Utils.ShortText

import qualified Distribution.Compat.ReadP as Parse
import qualified Distribution.Compat.CharParsing as P
import Distribution.Text
import Distribution.Pretty
import Distribution.Parsec.Class

import Text.PrettyPrint (text)

-- | ABI Hashes
--
-- Use 'mkAbiHash' and 'unAbiHash' to convert from/to a
-- 'String'.
--
-- This type is opaque since @Cabal-2.0@
--
-- @since 2.0.0.2
newtype AbiHash = AbiHash ShortText
    deriving (Eq, Show, Read, Generic)

-- | Construct a 'AbiHash' from a 'String'
--
-- 'mkAbiHash' is the inverse to 'unAbiHash'
--
-- Note: No validations are performed to ensure that the resulting
-- 'AbiHash' is valid
--
-- @since 2.0.0.2
unAbiHash :: AbiHash -> String
unAbiHash (AbiHash h) = fromShortText h

-- | Convert 'AbiHash' to 'String'
--
-- @since 2.0.0.2
mkAbiHash :: String -> AbiHash
mkAbiHash = AbiHash . toShortText

-- | 'mkAbiHash'
--
-- @since 2.0.0.2
instance IsString AbiHash where
    fromString = mkAbiHash

instance Binary AbiHash

instance NFData AbiHash where rnf = genericRnf

instance Pretty AbiHash where
    pretty = text . unAbiHash

instance Parsec AbiHash where
    parsec = fmap mkAbiHash (P.munch isAlphaNum)

instance Text AbiHash where
    parse = fmap mkAbiHash (Parse.munch isAlphaNum)
