content: -- | This stuff here is related to supporting the Safe Haskell extension,
  -- primarily about storing under what trust type a module has been compiled.
  module GHC.Types.SafeHaskell
     ( IsSafeImport
     , SafeHaskellMode(..)
     , IfaceTrustInfo
     , getSafeMode
     , setSafeMode
     , noIfaceTrustInfo
     )
  where
  
  import GHC.Prelude
  
  import GHC.Utils.Binary
  import GHC.Utils.Outputable
  import Control.DeepSeq
  
  import Data.Word
  
  
  -- | Is an import a safe import?
  type IsSafeImport = Bool
  
  -- | The various Safe Haskell modes
  data SafeHaskellMode
     = Sf_None          -- ^ inferred unsafe
     | Sf_Unsafe        -- ^ declared and checked
     | Sf_Trustworthy   -- ^ declared and checked
     | Sf_Safe          -- ^ declared and checked
     | Sf_SafeInferred  -- ^ inferred as safe
     | Sf_Ignore        -- ^ @-fno-safe-haskell@ state
     deriving (Eq)
  
  instance NFData SafeHaskellMode where
    rnf x = case x of
              Sf_None -> ()
              Sf_Unsafe -> ()
              Sf_Trustworthy -> ()
              Sf_Safe -> ()
              Sf_SafeInferred -> ()
              Sf_Ignore -> ()
  
  instance Show SafeHaskellMode where
      show Sf_None         = "None"
      show Sf_Unsafe       = "Unsafe"
      show Sf_Trustworthy  = "Trustworthy"
      show Sf_Safe         = "Safe"
      show Sf_SafeInferred = "Safe-Inferred"
      show Sf_Ignore       = "Ignore"
  
  instance Outputable SafeHaskellMode where
      ppr = text . show
  
  -- | Safe Haskell information for 'ModIface'
  -- Simply a wrapper around SafeHaskellMode to separate iface and flags
  newtype IfaceTrustInfo = TrustInfo SafeHaskellMode
  
  instance NFData IfaceTrustInfo where
    rnf (TrustInfo shm) = rnf shm
  
  
  getSafeMode :: IfaceTrustInfo -> SafeHaskellMode
  getSafeMode (TrustInfo x) = x
  
  setSafeMode :: SafeHaskellMode -> IfaceTrustInfo
  setSafeMode = TrustInfo
  
  noIfaceTrustInfo :: IfaceTrustInfo
  noIfaceTrustInfo = setSafeMode Sf_None
  
  trustInfoToNum :: IfaceTrustInfo -> Word8
  trustInfoToNum it
    = case getSafeMode it of
              Sf_None         -> 0
              Sf_Unsafe       -> 1
              Sf_Trustworthy  -> 2
              Sf_Safe         -> 3
              Sf_SafeInferred -> 4
              Sf_Ignore       -> 0
  
  numToTrustInfo :: Word8 -> IfaceTrustInfo
  numToTrustInfo 0 = setSafeMode Sf_None
  numToTrustInfo 1 = setSafeMode Sf_Unsafe
  numToTrustInfo 2 = setSafeMode Sf_Trustworthy
  numToTrustInfo 3 = setSafeMode Sf_Safe
  numToTrustInfo 4 = setSafeMode Sf_SafeInferred
  numToTrustInfo n = error $ "numToTrustInfo: bad input number! (" ++ show n ++ ")"
  
  instance Outputable IfaceTrustInfo where
      ppr (TrustInfo Sf_None)          = text "none"
      ppr (TrustInfo Sf_Ignore)        = text "none"
      ppr (TrustInfo Sf_Unsafe)        = text "unsafe"
      ppr (TrustInfo Sf_Trustworthy)   = text "trustworthy"
      ppr (TrustInfo Sf_Safe)          = text "safe"
      ppr (TrustInfo Sf_SafeInferred)  = text "safe-inferred"
  
  instance Binary IfaceTrustInfo where
      put_ bh iftrust = putByte bh $ trustInfoToNum iftrust
      get bh = getByte bh >>= (return . numToTrustInfo)
  