{-# LANGUAGE CPP #-}

-- | Why does this module exist? There is "GHC.ByteOrder" in base.
-- But that module is /broken/ until base-4.14/ghc-8.10, so we
-- can't rely on it until we drop support for older ghcs.
-- See https://gitlab.haskell.org/ghc/ghc/-/issues/20338
-- and https://gitlab.haskell.org/ghc/ghc/-/issues/18445

#include "MachDeps.h"

module Data.ByteString.Utils.ByteOrder
  ( ByteOrder(..)
  , hostByteOrder
  , whenLittleEndian
  , whenBigEndian
  ) where

data ByteOrder
  = LittleEndian
  | BigEndian

hostByteOrder :: ByteOrder
hostByteOrder :: ByteOrder
hostByteOrder =
#ifdef WORDS_BIGENDIAN
  BigEndian
#else
  ByteOrder
LittleEndian
#endif

-- | If the host is little-endian, applies the given function to the given arg.
-- If the host is big-endian, returns the second argument unchanged.
whenLittleEndian :: (a -> a) -> a -> a
whenLittleEndian :: forall a. (a -> a) -> a -> a
whenLittleEndian a -> a
fun a
val = case ByteOrder
hostByteOrder of
  ByteOrder
LittleEndian -> a -> a
fun a
val
  ByteOrder
BigEndian    -> a
val

-- | If the host is little-endian, returns the second argument unchanged.
-- If the host is big-endian, applies the given function to the given arg.
whenBigEndian :: (a -> a) -> a -> a
whenBigEndian :: forall a. (a -> a) -> a -> a
whenBigEndian a -> a
fun a
val = case ByteOrder
hostByteOrder of
  ByteOrder
LittleEndian -> a
val
  ByteOrder
BigEndian    -> a -> a
fun a
val