packages feed

toxcore-0.0.2: src/Network/Tox/C/CEnum.hs

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables        #-}
module Network.Tox.C.CEnum where

import           Control.Applicative   ((<$>))
import           Foreign.C.Types       (CInt)
import           Foreign.Marshal.Alloc (alloca)
import           Foreign.Ptr           (Ptr)
import           Foreign.Storable      (Storable (..))


newtype CEnum a = CEnum { unCEnum :: CInt }
  deriving (Storable)

instance (Enum a, Show a) => Show (CEnum a) where
  show cen = show (toEnum $ fromIntegral $ unCEnum cen :: a)


toCEnum :: Enum a => a -> CEnum a
toCEnum = CEnum . fromIntegral . fromEnum


fromCEnum :: Enum a => CEnum a -> a
fromCEnum = toEnum . fromIntegral . unCEnum


type CErr err = Ptr (CEnum err)

callErrFun :: (Eq err, Enum err, Bounded err)
           => (CErr err -> IO r) -> IO (Either err r)
callErrFun f = alloca $ \errPtr -> do
  res <- f errPtr
  err <- toEnum . fromIntegral . unCEnum <$> peek errPtr
  return $ if err /= minBound
    then Left  err
    else Right res