{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StrictData #-}
module Raft.Types where
import Protolude
import Data.Serialize
import Numeric.Natural (Natural)
import Database.PostgreSQL.Simple.ToField
import Database.PostgreSQL.Simple.FromField
type NodeId = ByteString
type NodeIds = Set NodeId
newtype ClientId = ClientId NodeId
deriving stock (Show, Read, Eq, Ord, Generic)
deriving newtype Serialize
newtype LeaderId = LeaderId { unLeaderId :: NodeId }
deriving stock (Show, Read, Eq, Generic)
deriving newtype Serialize
data CurrentLeader
= CurrentLeader LeaderId
| NoLeader
deriving stock (Show, Eq, Generic)
deriving anyclass (Serialize)
data Mode
= Follower
| Candidate
| Leader
deriving (Show, Read)
newtype Term = Term Natural
deriving stock (Generic)
deriving newtype (Show, Eq, Ord, Enum, Serialize)
instance ToField Term where
toField (Term n) = toField (fromIntegral n :: Int)
instance FromField Term where
fromField f mdata =
case (intToNatural <=< readEither) . toS <$> mdata of
Nothing -> returnError UnexpectedNull f ""
Just (Left err) -> returnError ConversionFailed f err
Just (Right nat) -> return (Term nat)
intToNatural :: Int -> Either [Char] Natural
intToNatural n
| n < 0 = Left "Natural numbers must be >= 0"
| otherwise = Right (fromIntegral n)
term0 :: Term
term0 = Term 0
incrTerm :: Term -> Term
incrTerm = succ
prevTerm :: Term -> Term
prevTerm (Term 0) = Term 0
prevTerm t = pred t
newtype Index = Index Natural
deriving stock (Show, Read, Generic)
deriving newtype (Eq, Ord, Enum, Num, Integral, Real, Serialize)
instance ToField Index where
toField (Index n) = toField (fromIntegral n :: Int)
instance FromField Index where
fromField f mdata =
case (intToNatural <=< readEither) . toS <$> mdata of
Nothing -> returnError UnexpectedNull f ""
Just (Left err) -> returnError ConversionFailed f err
Just (Right nat) -> return (Index nat)
index0 :: Index
index0 = Index 0
incrIndex :: Index -> Index
incrIndex = succ
decrIndexWithDefault0 :: Index -> Index
decrIndexWithDefault0 (Index 0) = index0
decrIndexWithDefault0 i = pred i
newtype SerialNum = SerialNum Natural
deriving stock (Show, Read, Generic)
deriving newtype (Eq, Ord, Enum, Num, Serialize)