{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{- |
  This module contains the PartitionKey type.
-}
module Network.Legion.PartitionKey (
  PartitionKey(..),
) where


import Data.Binary (Binary(put, get))
import Data.DoubleWord (Word256(Word256), Word128(Word128))
import Data.Ranged (DiscreteOrdered(adjacent, adjacentBelow))


{- | This is how partitions are identified and referenced. -}
newtype PartitionKey = K {
    unKey :: Word256
  }
  deriving (Eq, Ord, Show, Bounded, Enum)

instance Binary PartitionKey where
  put (K (Word256 (Word128 a b) (Word128 c d))) = put (a, b, c, d)
  get = do
    (a, b, c, d) <- get
    return (K (Word256 (Word128 a b) (Word128 c d)))

instance DiscreteOrdered PartitionKey where
  adjacent (K a) (K b) = a < b && succ a == b
  adjacentBelow (K k) = if k == minBound then Nothing else Just (K (pred k))