module Sound.JACK.Exception (
ToString(toString), toStringWithHead,
All,
ThrowsStatus (status), Status(..),
ThrowsPortRegister (portRegister), PortRegister(..),
ThrowsPortMismatch (portMismatch), PortMismatch(..), PortMismatchKind(..),
ThrowsErrno (errno), Errno(..),
) where
import qualified Sound.JACK.FFI as JackFFI
import qualified Foreign.C.Error as FE
import qualified Data.EnumSet as ES
import Data.Bits (Bits, )
type All = Status (PortRegister (PortMismatch FE.Errno))
toStringWithHead ::
All -> String
toStringWithHead e =
"JACK exception: " ++ toString e
class ToString e where
toString :: e -> String
instance (Bits w, Enum a, Show a) => ToString (ES.T w a) where
toString = show . ES.toEnums
class ThrowsStatus e where
status :: JackFFI.StatusSet -> e
data Status e =
Status JackFFI.StatusSet
| NoStatus e
instance ToString e => ToString (Status e) where
toString e0 =
case e0 of
Status st -> toString st
NoStatus e1 -> toString e1
instance ThrowsStatus (Status e) where
status = Status
instance ThrowsPortRegister e => ThrowsPortRegister (Status e) where
portRegister = NoStatus portRegister
instance ThrowsPortMismatch e => ThrowsPortMismatch (Status e) where
portMismatch = NoStatus . portMismatch
instance ThrowsErrno e => ThrowsErrno (Status e) where
errno = NoStatus . errno
class ThrowsPortRegister e where
portRegister :: e
data PortRegister e =
PortRegister
| NoPortRegister e
instance ToString e => ToString (PortRegister e) where
toString e0 =
case e0 of
PortRegister -> "could not register port"
NoPortRegister e1 -> toString e1
instance ThrowsStatus e => ThrowsStatus (PortRegister e) where
status = NoPortRegister . status
instance ThrowsPortRegister (PortRegister e) where
portRegister = PortRegister
instance ThrowsPortMismatch e => ThrowsPortMismatch (PortRegister e) where
portMismatch = NoPortRegister . portMismatch
instance ThrowsErrno e => ThrowsErrno (PortRegister e) where
errno = NoPortRegister . errno
class ThrowsPortMismatch e where
portMismatch :: PortMismatchKind -> e
data PortMismatch e =
PortMismatch PortMismatchKind
| NoPortMismatch e
data PortMismatchKind = TypeMismatch | DirectionMismatch
instance ToString e => ToString (PortMismatch e) where
toString e0 =
case e0 of
PortMismatch TypeMismatch -> "port not of excpected type"
PortMismatch DirectionMismatch -> "port does not support excpected direction"
NoPortMismatch e1 -> toString e1
instance ThrowsStatus e => ThrowsStatus (PortMismatch e) where
status = NoPortMismatch . status
instance ThrowsPortRegister e => ThrowsPortRegister (PortMismatch e) where
portRegister = NoPortMismatch portRegister
instance ThrowsPortMismatch (PortMismatch e) where
portMismatch = PortMismatch
instance ThrowsErrno e => ThrowsErrno (PortMismatch e) where
errno = NoPortMismatch . errno
class ThrowsErrno e where
errno :: FE.Errno -> e
data Errno e =
Errno FE.Errno
| NoErrno e
instance ToString e => ToString (Errno e) where
toString e0 =
case e0 of
Errno en -> toString en
NoErrno e1 -> toString e1
instance ToString FE.Errno where
toString (FE.Errno en) = "error code " ++ show en
instance ThrowsStatus e => ThrowsStatus (Errno e) where
status = NoErrno . status
instance ThrowsPortRegister e => ThrowsPortRegister (Errno e) where
portRegister = NoErrno portRegister
instance ThrowsPortMismatch e => ThrowsPortMismatch (Errno e) where
portMismatch = NoErrno . portMismatch
instance ThrowsErrno (Errno e) where
errno = Errno
instance ThrowsErrno FE.Errno where
errno = id