-- |
-- Module:      Data.ProtoBuf.WireTag
-- Copyright:   (c) 2015-2016 Martijn Rijkeboer <mrr@sru-systems.com>
-- License:     MIT
-- Maintainer:  Martijn Rijkeboer <mrr@sru-systems.com>
--
-- WireTag type and functions.

module Data.ProtoBuf.WireTag
    ( WireTag(..)
    , fromWireTag
    , toWireTag
    ) where


import Data.Bits ((.|.))
import Data.ProtoBuf.FieldNumber (fromFieldNumber, toFieldNumber, FieldNumber)
import Data.ProtoBuf.WireType (fromWireType, toWireType, WireType)
import Data.Word (Word32)


-- | Type to represent a wire tag.
data WireTag = WireTag FieldNumber WireType
    deriving (Int -> WireTag -> ShowS
[WireTag] -> ShowS
WireTag -> String
(Int -> WireTag -> ShowS)
-> (WireTag -> String) -> ([WireTag] -> ShowS) -> Show WireTag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WireTag] -> ShowS
$cshowList :: [WireTag] -> ShowS
show :: WireTag -> String
$cshow :: WireTag -> String
showsPrec :: Int -> WireTag -> ShowS
$cshowsPrec :: Int -> WireTag -> ShowS
Show, WireTag -> WireTag -> Bool
(WireTag -> WireTag -> Bool)
-> (WireTag -> WireTag -> Bool) -> Eq WireTag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WireTag -> WireTag -> Bool
$c/= :: WireTag -> WireTag -> Bool
== :: WireTag -> WireTag -> Bool
$c== :: WireTag -> WireTag -> Bool
Eq, Eq WireTag
Eq WireTag
-> (WireTag -> WireTag -> Ordering)
-> (WireTag -> WireTag -> Bool)
-> (WireTag -> WireTag -> Bool)
-> (WireTag -> WireTag -> Bool)
-> (WireTag -> WireTag -> Bool)
-> (WireTag -> WireTag -> WireTag)
-> (WireTag -> WireTag -> WireTag)
-> Ord WireTag
WireTag -> WireTag -> Bool
WireTag -> WireTag -> Ordering
WireTag -> WireTag -> WireTag
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: WireTag -> WireTag -> WireTag
$cmin :: WireTag -> WireTag -> WireTag
max :: WireTag -> WireTag -> WireTag
$cmax :: WireTag -> WireTag -> WireTag
>= :: WireTag -> WireTag -> Bool
$c>= :: WireTag -> WireTag -> Bool
> :: WireTag -> WireTag -> Bool
$c> :: WireTag -> WireTag -> Bool
<= :: WireTag -> WireTag -> Bool
$c<= :: WireTag -> WireTag -> Bool
< :: WireTag -> WireTag -> Bool
$c< :: WireTag -> WireTag -> Bool
compare :: WireTag -> WireTag -> Ordering
$ccompare :: WireTag -> WireTag -> Ordering
$cp1Ord :: Eq WireTag
Ord)


-- | Convert a WireTag into a Word32.
fromWireTag :: WireTag -> Word32
fromWireTag :: WireTag -> Word32
fromWireTag (WireTag FieldNumber
fn WireType
wt) = FieldNumber -> Word32
fromFieldNumber FieldNumber
fn Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. WireType -> Word32
fromWireType WireType
wt


-- | Convert a Word32 into a WireTag or an error.
toWireTag :: Word32 -> Either String WireTag
toWireTag :: Word32 -> Either String WireTag
toWireTag Word32
i = do
    FieldNumber
fieldNumber <- Word32 -> Either String FieldNumber
toFieldNumber Word32
i
    WireType
wireType    <- Word32 -> Either String WireType
toWireType Word32
i
    WireTag -> Either String WireTag
forall (m :: * -> *) a. Monad m => a -> m a
return (WireTag -> Either String WireTag)
-> WireTag -> Either String WireTag
forall a b. (a -> b) -> a -> b
$ FieldNumber -> WireType -> WireTag
WireTag FieldNumber
fieldNumber WireType
wireType