{-# LANGUAGE BangPatterns #-}
module Database.PostgreSQL.Types.LSN
( LSN(..)
, encodeLSN
, decodeLSN
, lsnParser
) where
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Lazy.Builder as Builder
import Data.ByteString.Lazy.Builder.ASCII (word32Hex, word32HexFixed)
import Data.Monoid ((<>))
import Data.Word
import Data.Attoparsec.ByteString.Char8
data LSN = LSN
{ filepart :: !Word32
, offset :: !Word32
}
deriving (Show, Eq)
instance Ord LSN where
compare (LSN l0 r0) (LSN l1 r1)
| l0 > l1 || (l0 == l1 && r0 > r1) = GT
| l0 < l1 || (l0 == l1 && r0 < r1) = LT
| otherwise = EQ
lsnParser :: Parser LSN
lsnParser = LSN <$> (hexadecimal <* char '/') <*> hexadecimal
decodeLSN :: ByteString -> Either String LSN
decodeLSN = parseOnly lsnParser
encodeLSN :: LSN -> ByteString
encodeLSN (LSN filepart off) = BL.toStrict $ Builder.toLazyByteString (word32Hex filepart <> Builder.char7 '/' <> word32Hex off)