{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}

module WGPU.Internal.ChainedStruct
  ( -- * Types
    ChainedStruct (..),
  )
where

import Foreign (Ptr, castPtr, nullPtr)
import WGPU.Internal.Memory (ToRaw, raw)
import WGPU.Raw.Generated.Enum.WGPUSType (WGPUSType)
import WGPU.Raw.Generated.Struct.WGPUChainedStruct (WGPUChainedStruct)
import qualified WGPU.Raw.Generated.Struct.WGPUChainedStruct as WGPUChainedStruct

-------------------------------------------------------------------------------

-- | Represents a chained structure.
data ChainedStruct a
  = -- | Empty chained structure, but with a type tag.
    EmptyChain WGPUSType
  | -- | Chained structue that points to the next structure in a chain.
    PtrChain WGPUSType (Ptr a)

instance ToRaw (ChainedStruct a) WGPUChainedStruct where
  raw :: ChainedStruct a -> ContT r IO WGPUChainedStruct
raw ChainedStruct a
chainedStruct =
    case ChainedStruct a
chainedStruct of
      EmptyChain WGPUSType
sType ->
        WGPUChainedStruct -> ContT r IO WGPUChainedStruct
forall (f :: * -> *) a. Applicative f => a -> f a
pure
          WGPUChainedStruct :: Ptr WGPUChainedStruct -> WGPUSType -> WGPUChainedStruct
WGPUChainedStruct.WGPUChainedStruct
            { next :: Ptr WGPUChainedStruct
next = Ptr WGPUChainedStruct
forall a. Ptr a
nullPtr,
              sType :: WGPUSType
sType = WGPUSType
sType
            }
      PtrChain WGPUSType
sType Ptr a
ptr ->
        WGPUChainedStruct -> ContT r IO WGPUChainedStruct
forall (f :: * -> *) a. Applicative f => a -> f a
pure
          WGPUChainedStruct :: Ptr WGPUChainedStruct -> WGPUSType -> WGPUChainedStruct
WGPUChainedStruct.WGPUChainedStruct
            { next :: Ptr WGPUChainedStruct
next = Ptr a -> Ptr WGPUChainedStruct
forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr,
              sType :: WGPUSType
sType = WGPUSType
sType
            }