module Authorize.Macaroon.Serialize ( fieldEOS, fieldLocation, fieldIdentifier, fieldVerificationId, fieldSignature, putField, getField, getOptionalField, getEOS, atEOS, ) where import Data.ByteString (ByteString) import Data.ByteString qualified as BS import Data.Bytes.Serial qualified as By import Data.Bytes.VarInt (VarInt (..)) import Data.Serialize (Get, Put, Serialize (..)) import Data.Serialize qualified as S import Data.Word (Word8) fieldEOS :: Word8 fieldEOS :: Word8 fieldEOS = Word8 0 fieldLocation :: Word8 fieldLocation :: Word8 fieldLocation = Word8 1 fieldIdentifier :: Word8 fieldIdentifier :: Word8 fieldIdentifier = Word8 2 fieldVerificationId :: Word8 fieldVerificationId :: Word8 fieldVerificationId = Word8 4 fieldSignature :: Word8 fieldSignature :: Word8 fieldSignature = Word8 6 putField :: Word8 -> ByteString -> Put putField :: Word8 -> ByteString -> Put putField Word8 fieldId ByteString dat = Putter Word8 forall t. Serialize t => Putter t put Word8 fieldId Put -> Put -> Put forall a b. PutM a -> PutM b -> PutM b forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> VarInt Int -> Put forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m () forall (m :: * -> *). MonadPut m => VarInt Int -> m () By.serialize (Int -> VarInt Int forall n. n -> VarInt n VarInt (Int -> VarInt Int) -> Int -> VarInt Int forall a b. (a -> b) -> a -> b $ ByteString -> Int BS.length ByteString dat) Put -> Put -> Put forall a b. PutM a -> PutM b -> PutM b forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> ByteString -> Put S.putByteString ByteString dat getOptionalField :: Word8 -> Get (Maybe ByteString) getOptionalField :: Word8 -> Get (Maybe ByteString) getOptionalField Word8 f = do Word8 n <- Get Word8 -> Get Word8 forall a. Get a -> Get a S.lookAhead Get Word8 S.getWord8 if Word8 n Word8 -> Word8 -> Bool forall a. Eq a => a -> a -> Bool == Word8 f then Get Word8 S.getWord8 Get Word8 -> Get (Maybe ByteString) -> Get (Maybe ByteString) forall a b. Get a -> Get b -> Get b forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> ByteString -> Maybe ByteString forall a. a -> Maybe a Just (ByteString -> Maybe ByteString) -> Get ByteString -> Get (Maybe ByteString) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Get ByteString getFieldData else Maybe ByteString -> Get (Maybe ByteString) forall a. a -> Get a forall (m :: * -> *) a. Monad m => a -> m a return Maybe ByteString forall a. Maybe a Nothing getField :: Word8 -> Get ByteString getField :: Word8 -> Get ByteString getField Word8 f = do Word8 n <- Get Word8 S.getWord8 if Word8 n Word8 -> Word8 -> Bool forall a. Eq a => a -> a -> Bool == Word8 f then Get ByteString getFieldData else String -> Get ByteString forall a. String -> Get a forall (m :: * -> *) a. MonadFail m => String -> m a fail (String -> Get ByteString) -> String -> Get ByteString forall a b. (a -> b) -> a -> b $ String "Expecting field " String -> String -> String forall a. Semigroup a => a -> a -> a <> Word8 -> String forall a. Show a => a -> String show Word8 f String -> String -> String forall a. Semigroup a => a -> a -> a <> String " but got " String -> String -> String forall a. Semigroup a => a -> a -> a <> Word8 -> String forall a. Show a => a -> String show Word8 n getFieldData :: Get ByteString getFieldData :: Get ByteString getFieldData = do VarInt Int n <- Get (VarInt Int) forall a (m :: * -> *). (Serial a, MonadGet m) => m a forall (m :: * -> *). MonadGet m => m (VarInt Int) By.deserialize Int -> Get ByteString S.getBytes Int n getEOS :: Get () getEOS :: Get () getEOS = do Word8 f <- Get Word8 S.getWord8 if Word8 f Word8 -> Word8 -> Bool forall a. Eq a => a -> a -> Bool == Word8 fieldEOS then () -> Get () forall a. a -> Get a forall (m :: * -> *) a. Monad m => a -> m a return () else String -> Get () forall a. String -> Get a forall (m :: * -> *) a. MonadFail m => String -> m a fail String "Expecting EOS" atEOS :: Get Bool atEOS :: Get Bool atEOS = (Word8 -> Word8 -> Bool forall a. Eq a => a -> a -> Bool == Word8 fieldEOS) (Word8 -> Bool) -> Get Word8 -> Get Bool forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Get Word8 -> Get Word8 forall a. Get a -> Get a S.lookAhead Get Word8 S.getWord8