module Data.Bool8 (
   Bool8,
   false, true,
   toBool,
   fromBool,
   ) where

import Foreign.Storable (Storable, poke, peek, sizeOf, alignment)
import Foreign.Ptr (Ptr, castPtr)

import Data.Functor ((<$>))
import Data.Word (Word8)


newtype Bool8 = Bool8 Bool
   deriving (Eq, Ord)

instance Show Bool8 where
   show (Bool8 False) = "Bool8.false"
   show _ = "Bool8.true"

instance Bounded Bool8 where
   minBound = false
   maxBound = true

word8Ptr :: Ptr Bool8 -> Ptr Word8
word8Ptr = castPtr

instance Storable Bool8 where
   sizeOf _ = 1
   alignment _ = 1
   peek ptr = Bool8 . (0/=) <$> peek (word8Ptr ptr)
   poke ptr (Bool8 b) = poke (word8Ptr ptr) (fromIntegral $ fromEnum b)

instance Enum Bool8 where
   fromEnum (Bool8 b) = fromEnum b
   toEnum = Bool8 . toEnum

false, true :: Bool8
false = Bool8 False
true = Bool8 True

toBool :: Bool8 -> Bool
toBool (Bool8 b) = b

fromBool :: Bool -> Bool8
fromBool = Bool8