content: {-# LANGUAGE CPP #-}
  {-# LANGUAGE DeriveDataTypeable #-}
  {-# LANGUAGE DeriveGeneric #-}
  
  module Distribution.Utils.ShortText
      ( -- * 'ShortText' type
        ShortText
      , toShortText
      , fromShortText
  
        -- * internal utilities
      , decodeStringUtf8
      , encodeStringUtf8
      ) where
  
  import Prelude ()
  import Distribution.Compat.Prelude
  import Distribution.Utils.String
  
  #if defined(MIN_VERSION_bytestring)
  # if MIN_VERSION_bytestring(0,10,4)
  # define HAVE_SHORTBYTESTRING 1
  # endif
  #endif
  
  -- Hack for GHC bootstrapping
  --
  -- Currently (as of GHC 8.1), GHC bootstraps Cabal by building
  -- binary and Cabal in one giant ghc --make command.  This
  -- means no MIN_VERSION_binary macro is available.
  --
  -- We could try to cleverly figure something out in this case,
  -- but there is a better plan: just use the unoptimized version
  -- of the Binary instance.  We're not going to use it for anything
  -- real in any case.
  --
  -- WARNING: Don't use MIN_VERSION_binary to smooth over a BC-break!
  --
  #ifndef MIN_VERSION_binary
  #define MIN_VERSION_binary(x, y, z) 0
  #endif
  
  #if HAVE_SHORTBYTESTRING
  import qualified Data.ByteString.Short as BS.Short
  #endif
  
  -- | Construct 'ShortText' from 'String'
  toShortText :: String -> ShortText
  
  -- | Convert 'ShortText' to 'String'
  fromShortText :: ShortText -> String
  
  -- | Compact representation of short 'Strings'
  --
  -- The data is stored internally as UTF8 in an
  -- 'BS.Short.ShortByteString' when compiled against @bytestring >=
  -- 0.10.4@, and otherwise the fallback is to use plain old non-compat
  -- '[Char]'.
  --
  -- Note: This type is for internal uses (such as e.g. 'PackageName')
  -- and shall not be exposed in Cabal's API
  --
  -- @since 2.0.0
  #if HAVE_SHORTBYTESTRING
  newtype ShortText = ST { unST :: BS.Short.ShortByteString }
                    deriving (Eq,Ord,Generic,Data,Typeable)
  
  # if MIN_VERSION_binary(0,8,1)
  instance Binary ShortText where
      put = put . unST
      get = fmap ST get
  # else
  instance Binary ShortText where
      put = put . BS.Short.fromShort . unST
      get = fmap (ST . BS.Short.toShort) get
  # endif
  
  toShortText = ST . BS.Short.pack . encodeStringUtf8
  
  fromShortText = decodeStringUtf8 . BS.Short.unpack . unST
  #else
  newtype ShortText = ST { unST :: String }
                    deriving (Eq,Ord,Generic,Data,Typeable)
  
  instance Binary ShortText where
      put = put . encodeStringUtf8 . unST
      get = fmap (ST . decodeStringUtf8) get
  
  toShortText = ST
  
  fromShortText = unST
  #endif
  
  instance NFData ShortText where
      rnf = rnf . unST
  
  instance Show ShortText where
      show = show . fromShortText
  
  instance Read ShortText where
      readsPrec p = map (first toShortText) . readsPrec p
  
  instance Semigroup ShortText where
      ST a <> ST b = ST (mappend a b)
  
  instance Monoid ShortText where
      mempty = ST mempty
      mappend = (<>)
  
  instance IsString ShortText where
      fromString = toShortText
  