-- |
-- Module      : Data.Endian
-- Description : Newtypes for little- and big-endian values
-- Copyright   : (c) Aleksey Makarov, 2021
-- License     : BSD 3-Clause License
-- Maintainer  : aleksey.makarov@gmail.com
-- Stability   : experimental
-- Portability : portable
--
-- Newtypes for little- and big-endian instances of `Binary`

{-# LANGUAGE FlexibleInstances #-}

module Data.Endian (Be(..), Le(..)) where

import Data.Binary.Put
import Data.Binary.Get
import Data.Binary

-- | @Be a@ is an instance of `Binary` such that @a@ is serialized as big-endian
newtype Be a = Be { forall a. Be a -> a
fromBe :: a } deriving Be a -> Be a -> Bool
(Be a -> Be a -> Bool) -> (Be a -> Be a -> Bool) -> Eq (Be a)
forall a. Eq a => Be a -> Be a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Be a -> Be a -> Bool
== :: Be a -> Be a -> Bool
$c/= :: forall a. Eq a => Be a -> Be a -> Bool
/= :: Be a -> Be a -> Bool
Eq

-- | @Le a@ is an instance of `Binary` such that @a@ is serialized as little-endian
newtype Le a = Le { forall a. Le a -> a
fromLe :: a } deriving Le a -> Le a -> Bool
(Le a -> Le a -> Bool) -> (Le a -> Le a -> Bool) -> Eq (Le a)
forall a. Eq a => Le a -> Le a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Le a -> Le a -> Bool
== :: Le a -> Le a -> Bool
$c/= :: forall a. Eq a => Le a -> Le a -> Bool
/= :: Le a -> Le a -> Bool
Eq

instance Binary (Be Word16) where
    put :: Be Word16 -> Put
put = Word16 -> Put
putWord16be (Word16 -> Put) -> (Be Word16 -> Word16) -> Be Word16 -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Be Word16 -> Word16
forall a. Be a -> a
fromBe
    get :: Get (Be Word16)
get = Word16 -> Be Word16
forall a. a -> Be a
Be (Word16 -> Be Word16) -> Get Word16 -> Get (Be Word16)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word16
getWord16be

instance Binary (Le Word16) where
    put :: Le Word16 -> Put
put = Word16 -> Put
putWord16le (Word16 -> Put) -> (Le Word16 -> Word16) -> Le Word16 -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Le Word16 -> Word16
forall a. Le a -> a
fromLe
    get :: Get (Le Word16)
get = Word16 -> Le Word16
forall a. a -> Le a
Le (Word16 -> Le Word16) -> Get Word16 -> Get (Le Word16)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word16
getWord16le

instance Binary (Be Word32) where
    put :: Be Word32 -> Put
put = Word32 -> Put
putWord32be (Word32 -> Put) -> (Be Word32 -> Word32) -> Be Word32 -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Be Word32 -> Word32
forall a. Be a -> a
fromBe
    get :: Get (Be Word32)
get = Word32 -> Be Word32
forall a. a -> Be a
Be (Word32 -> Be Word32) -> Get Word32 -> Get (Be Word32)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word32
getWord32be

instance Binary (Le Word32) where
    put :: Le Word32 -> Put
put = Word32 -> Put
putWord32le (Word32 -> Put) -> (Le Word32 -> Word32) -> Le Word32 -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Le Word32 -> Word32
forall a. Le a -> a
fromLe
    get :: Get (Le Word32)
get = Word32 -> Le Word32
forall a. a -> Le a
Le (Word32 -> Le Word32) -> Get Word32 -> Get (Le Word32)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word32
getWord32le

instance Binary (Be Word64) where
    put :: Be Word64 -> Put
put = Word64 -> Put
putWord64be (Word64 -> Put) -> (Be Word64 -> Word64) -> Be Word64 -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Be Word64 -> Word64
forall a. Be a -> a
fromBe
    get :: Get (Be Word64)
get = Word64 -> Be Word64
forall a. a -> Be a
Be (Word64 -> Be Word64) -> Get Word64 -> Get (Be Word64)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word64
getWord64be

instance Binary (Le Word64) where
    put :: Le Word64 -> Put
put = Word64 -> Put
putWord64le (Word64 -> Put) -> (Le Word64 -> Word64) -> Le Word64 -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Le Word64 -> Word64
forall a. Le a -> a
fromLe
    get :: Get (Le Word64)
get = Word64 -> Le Word64
forall a. a -> Le a
Le (Word64 -> Le Word64) -> Get Word64 -> Get (Le Word64)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word64
getWord64le