{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}

-- This file is part of the Wire Server implementation.
--
-- Copyright (C) 2022 Wire Swiss GmbH <opensource@wire.com>
--
-- This program is free software: you can redistribute it and/or modify it under
-- the terms of the GNU Affero General Public License as published by the Free
-- Software Foundation, either version 3 of the License, or (at your option) any
-- later version.
--
-- This program is distributed in the hope that it will be useful, but WITHOUT
-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
-- details.
--
-- You should have received a copy of the GNU Affero General Public License along
-- with this program. If not, see <https://www.gnu.org/licenses/>.

module Wire.API.MLS.Proposal where

import Cassandra
import Control.Lens (makePrisms)
import Data.Binary
import Data.ByteString as B
import GHC.Records
import Imports
import Test.QuickCheck
import Wire.API.MLS.CipherSuite
import Wire.API.MLS.Extension
import Wire.API.MLS.Group
import Wire.API.MLS.KeyPackage
import Wire.API.MLS.LeafNode
import Wire.API.MLS.ProposalTag
import Wire.API.MLS.ProtocolVersion
import Wire.API.MLS.Serialisation
import Wire.Arbitrary

-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-12.1-2
data Proposal
  = AddProposal (RawMLS KeyPackage)
  | UpdateProposal (RawMLS LeafNode)
  | RemoveProposal LeafIndex
  | PreSharedKeyProposal (RawMLS PreSharedKeyID)
  | ReInitProposal (RawMLS ReInit)
  | ExternalInitProposal ByteString
  | GroupContextExtensionsProposal [Extension]
  deriving stock (Proposal -> Proposal -> Bool
(Proposal -> Proposal -> Bool)
-> (Proposal -> Proposal -> Bool) -> Eq Proposal
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Proposal -> Proposal -> Bool
== :: Proposal -> Proposal -> Bool
$c/= :: Proposal -> Proposal -> Bool
/= :: Proposal -> Proposal -> Bool
Eq, Int -> Proposal -> ShowS
[Proposal] -> ShowS
Proposal -> String
(Int -> Proposal -> ShowS)
-> (Proposal -> String) -> ([Proposal] -> ShowS) -> Show Proposal
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Proposal -> ShowS
showsPrec :: Int -> Proposal -> ShowS
$cshow :: Proposal -> String
show :: Proposal -> String
$cshowList :: [Proposal] -> ShowS
showList :: [Proposal] -> ShowS
Show, (forall x. Proposal -> Rep Proposal x)
-> (forall x. Rep Proposal x -> Proposal) -> Generic Proposal
forall x. Rep Proposal x -> Proposal
forall x. Proposal -> Rep Proposal x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Proposal -> Rep Proposal x
from :: forall x. Proposal -> Rep Proposal x
$cto :: forall x. Rep Proposal x -> Proposal
to :: forall x. Rep Proposal x -> Proposal
Generic)
  deriving (Gen Proposal
Gen Proposal -> (Proposal -> [Proposal]) -> Arbitrary Proposal
Proposal -> [Proposal]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen Proposal
arbitrary :: Gen Proposal
$cshrink :: Proposal -> [Proposal]
shrink :: Proposal -> [Proposal]
Arbitrary) via (GenericUniform Proposal)

instance HasField "tag" Proposal ProposalTag where
  getField :: Proposal -> ProposalTag
getField (AddProposal RawMLS KeyPackage
_) = ProposalTag
AddProposalTag
  getField (UpdateProposal RawMLS LeafNode
_) = ProposalTag
UpdateProposalTag
  getField (RemoveProposal LeafIndex
_) = ProposalTag
RemoveProposalTag
  getField (PreSharedKeyProposal RawMLS PreSharedKeyID
_) = ProposalTag
PreSharedKeyProposalTag
  getField (ReInitProposal RawMLS ReInit
_) = ProposalTag
ReInitProposalTag
  getField (ExternalInitProposal ByteString
_) = ProposalTag
ExternalInitProposalTag
  getField (GroupContextExtensionsProposal [Extension]
_) = ProposalTag
GroupContextExtensionsProposalTag

instance ParseMLS Proposal where
  parseMLS :: Get Proposal
parseMLS =
    Get ProposalTag
forall a. ParseMLS a => Get a
parseMLS Get ProposalTag -> (ProposalTag -> Get Proposal) -> Get Proposal
forall a b. Get a -> (a -> Get b) -> Get b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      ProposalTag
AddProposalTag -> RawMLS KeyPackage -> Proposal
AddProposal (RawMLS KeyPackage -> Proposal)
-> Get (RawMLS KeyPackage) -> Get Proposal
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (RawMLS KeyPackage)
forall a. ParseMLS a => Get a
parseMLS
      ProposalTag
UpdateProposalTag -> RawMLS LeafNode -> Proposal
UpdateProposal (RawMLS LeafNode -> Proposal)
-> Get (RawMLS LeafNode) -> Get Proposal
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (RawMLS LeafNode)
forall a. ParseMLS a => Get a
parseMLS
      ProposalTag
RemoveProposalTag -> LeafIndex -> Proposal
RemoveProposal (LeafIndex -> Proposal) -> Get LeafIndex -> Get Proposal
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get LeafIndex
forall a. ParseMLS a => Get a
parseMLS
      ProposalTag
PreSharedKeyProposalTag -> RawMLS PreSharedKeyID -> Proposal
PreSharedKeyProposal (RawMLS PreSharedKeyID -> Proposal)
-> Get (RawMLS PreSharedKeyID) -> Get Proposal
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (RawMLS PreSharedKeyID)
forall a. ParseMLS a => Get a
parseMLS
      ProposalTag
ReInitProposalTag -> RawMLS ReInit -> Proposal
ReInitProposal (RawMLS ReInit -> Proposal) -> Get (RawMLS ReInit) -> Get Proposal
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get (RawMLS ReInit)
forall a. ParseMLS a => Get a
parseMLS
      ProposalTag
ExternalInitProposalTag -> ByteString -> Proposal
ExternalInitProposal (ByteString -> Proposal) -> Get ByteString -> Get Proposal
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall w. (Binary w, Integral w) => Get ByteString
parseMLSBytes @VarInt
      ProposalTag
GroupContextExtensionsProposalTag ->
        [Extension] -> Proposal
GroupContextExtensionsProposal ([Extension] -> Proposal) -> Get [Extension] -> Get Proposal
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall w a. (Binary w, Integral w) => Get a -> Get [a]
parseMLSVector @VarInt Get Extension
forall a. ParseMLS a => Get a
parseMLS

instance SerialiseMLS Proposal where
  serialiseMLS :: Proposal -> Put
serialiseMLS (AddProposal RawMLS KeyPackage
kp) = do
    ProposalTag -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ProposalTag
AddProposalTag
    RawMLS KeyPackage -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS RawMLS KeyPackage
kp
  serialiseMLS (UpdateProposal RawMLS LeafNode
ln) = do
    ProposalTag -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ProposalTag
UpdateProposalTag
    RawMLS LeafNode -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS RawMLS LeafNode
ln
  serialiseMLS (RemoveProposal LeafIndex
i) = do
    ProposalTag -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ProposalTag
RemoveProposalTag
    LeafIndex -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS LeafIndex
i
  serialiseMLS (PreSharedKeyProposal RawMLS PreSharedKeyID
k) = do
    ProposalTag -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ProposalTag
PreSharedKeyProposalTag
    RawMLS PreSharedKeyID -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS RawMLS PreSharedKeyID
k
  serialiseMLS (ReInitProposal RawMLS ReInit
ri) = do
    ProposalTag -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ProposalTag
ReInitProposalTag
    RawMLS ReInit -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS RawMLS ReInit
ri
  serialiseMLS (ExternalInitProposal ByteString
ko) = do
    ProposalTag -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ProposalTag
ExternalInitProposalTag
    forall w. (Binary w, Integral w) => ByteString -> Put
serialiseMLSBytes @VarInt ByteString
ko
  serialiseMLS (GroupContextExtensionsProposal [Extension]
es) = do
    ProposalTag -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ProposalTag
GroupContextExtensionsProposalTag
    forall w a. (Binary w, Integral w) => (a -> Put) -> [a] -> Put
serialiseMLSVector @VarInt Extension -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS [Extension]
es

-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-8.4-6
data PreSharedKeyTag = ExternalKeyTag | ResumptionKeyTag
  deriving (PreSharedKeyTag
PreSharedKeyTag -> PreSharedKeyTag -> Bounded PreSharedKeyTag
forall a. a -> a -> Bounded a
$cminBound :: PreSharedKeyTag
minBound :: PreSharedKeyTag
$cmaxBound :: PreSharedKeyTag
maxBound :: PreSharedKeyTag
Bounded, Int -> PreSharedKeyTag
PreSharedKeyTag -> Int
PreSharedKeyTag -> [PreSharedKeyTag]
PreSharedKeyTag -> PreSharedKeyTag
PreSharedKeyTag -> PreSharedKeyTag -> [PreSharedKeyTag]
PreSharedKeyTag
-> PreSharedKeyTag -> PreSharedKeyTag -> [PreSharedKeyTag]
(PreSharedKeyTag -> PreSharedKeyTag)
-> (PreSharedKeyTag -> PreSharedKeyTag)
-> (Int -> PreSharedKeyTag)
-> (PreSharedKeyTag -> Int)
-> (PreSharedKeyTag -> [PreSharedKeyTag])
-> (PreSharedKeyTag -> PreSharedKeyTag -> [PreSharedKeyTag])
-> (PreSharedKeyTag -> PreSharedKeyTag -> [PreSharedKeyTag])
-> (PreSharedKeyTag
    -> PreSharedKeyTag -> PreSharedKeyTag -> [PreSharedKeyTag])
-> Enum PreSharedKeyTag
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: PreSharedKeyTag -> PreSharedKeyTag
succ :: PreSharedKeyTag -> PreSharedKeyTag
$cpred :: PreSharedKeyTag -> PreSharedKeyTag
pred :: PreSharedKeyTag -> PreSharedKeyTag
$ctoEnum :: Int -> PreSharedKeyTag
toEnum :: Int -> PreSharedKeyTag
$cfromEnum :: PreSharedKeyTag -> Int
fromEnum :: PreSharedKeyTag -> Int
$cenumFrom :: PreSharedKeyTag -> [PreSharedKeyTag]
enumFrom :: PreSharedKeyTag -> [PreSharedKeyTag]
$cenumFromThen :: PreSharedKeyTag -> PreSharedKeyTag -> [PreSharedKeyTag]
enumFromThen :: PreSharedKeyTag -> PreSharedKeyTag -> [PreSharedKeyTag]
$cenumFromTo :: PreSharedKeyTag -> PreSharedKeyTag -> [PreSharedKeyTag]
enumFromTo :: PreSharedKeyTag -> PreSharedKeyTag -> [PreSharedKeyTag]
$cenumFromThenTo :: PreSharedKeyTag
-> PreSharedKeyTag -> PreSharedKeyTag -> [PreSharedKeyTag]
enumFromThenTo :: PreSharedKeyTag
-> PreSharedKeyTag -> PreSharedKeyTag -> [PreSharedKeyTag]
Enum, PreSharedKeyTag -> PreSharedKeyTag -> Bool
(PreSharedKeyTag -> PreSharedKeyTag -> Bool)
-> (PreSharedKeyTag -> PreSharedKeyTag -> Bool)
-> Eq PreSharedKeyTag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PreSharedKeyTag -> PreSharedKeyTag -> Bool
== :: PreSharedKeyTag -> PreSharedKeyTag -> Bool
$c/= :: PreSharedKeyTag -> PreSharedKeyTag -> Bool
/= :: PreSharedKeyTag -> PreSharedKeyTag -> Bool
Eq, Int -> PreSharedKeyTag -> ShowS
[PreSharedKeyTag] -> ShowS
PreSharedKeyTag -> String
(Int -> PreSharedKeyTag -> ShowS)
-> (PreSharedKeyTag -> String)
-> ([PreSharedKeyTag] -> ShowS)
-> Show PreSharedKeyTag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PreSharedKeyTag -> ShowS
showsPrec :: Int -> PreSharedKeyTag -> ShowS
$cshow :: PreSharedKeyTag -> String
show :: PreSharedKeyTag -> String
$cshowList :: [PreSharedKeyTag] -> ShowS
showList :: [PreSharedKeyTag] -> ShowS
Show)

instance ParseMLS PreSharedKeyTag where
  parseMLS :: Get PreSharedKeyTag
parseMLS = forall w a.
(Bounded a, Enum a, Integral w, Binary w) =>
String -> Get a
parseMLSEnum @Word8 String
"PreSharedKeyID type"

instance SerialiseMLS PreSharedKeyTag where
  serialiseMLS :: PreSharedKeyTag -> Put
serialiseMLS = forall w a. (Enum a, Integral w, Binary w) => a -> Put
serialiseMLSEnum @Word8

-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-8.4-6
data PreSharedKeyIDCore = ExternalKeyID ByteString | ResumptionKeyID Resumption
  deriving stock (PreSharedKeyIDCore -> PreSharedKeyIDCore -> Bool
(PreSharedKeyIDCore -> PreSharedKeyIDCore -> Bool)
-> (PreSharedKeyIDCore -> PreSharedKeyIDCore -> Bool)
-> Eq PreSharedKeyIDCore
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PreSharedKeyIDCore -> PreSharedKeyIDCore -> Bool
== :: PreSharedKeyIDCore -> PreSharedKeyIDCore -> Bool
$c/= :: PreSharedKeyIDCore -> PreSharedKeyIDCore -> Bool
/= :: PreSharedKeyIDCore -> PreSharedKeyIDCore -> Bool
Eq, Int -> PreSharedKeyIDCore -> ShowS
[PreSharedKeyIDCore] -> ShowS
PreSharedKeyIDCore -> String
(Int -> PreSharedKeyIDCore -> ShowS)
-> (PreSharedKeyIDCore -> String)
-> ([PreSharedKeyIDCore] -> ShowS)
-> Show PreSharedKeyIDCore
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PreSharedKeyIDCore -> ShowS
showsPrec :: Int -> PreSharedKeyIDCore -> ShowS
$cshow :: PreSharedKeyIDCore -> String
show :: PreSharedKeyIDCore -> String
$cshowList :: [PreSharedKeyIDCore] -> ShowS
showList :: [PreSharedKeyIDCore] -> ShowS
Show, (forall x. PreSharedKeyIDCore -> Rep PreSharedKeyIDCore x)
-> (forall x. Rep PreSharedKeyIDCore x -> PreSharedKeyIDCore)
-> Generic PreSharedKeyIDCore
forall x. Rep PreSharedKeyIDCore x -> PreSharedKeyIDCore
forall x. PreSharedKeyIDCore -> Rep PreSharedKeyIDCore x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. PreSharedKeyIDCore -> Rep PreSharedKeyIDCore x
from :: forall x. PreSharedKeyIDCore -> Rep PreSharedKeyIDCore x
$cto :: forall x. Rep PreSharedKeyIDCore x -> PreSharedKeyIDCore
to :: forall x. Rep PreSharedKeyIDCore x -> PreSharedKeyIDCore
Generic)
  deriving (Gen PreSharedKeyIDCore
Gen PreSharedKeyIDCore
-> (PreSharedKeyIDCore -> [PreSharedKeyIDCore])
-> Arbitrary PreSharedKeyIDCore
PreSharedKeyIDCore -> [PreSharedKeyIDCore]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen PreSharedKeyIDCore
arbitrary :: Gen PreSharedKeyIDCore
$cshrink :: PreSharedKeyIDCore -> [PreSharedKeyIDCore]
shrink :: PreSharedKeyIDCore -> [PreSharedKeyIDCore]
Arbitrary) via (GenericUniform PreSharedKeyIDCore)

instance ParseMLS PreSharedKeyIDCore where
  parseMLS :: Get PreSharedKeyIDCore
parseMLS = do
    PreSharedKeyTag
t <- Get PreSharedKeyTag
forall a. ParseMLS a => Get a
parseMLS
    case PreSharedKeyTag
t of
      PreSharedKeyTag
ExternalKeyTag -> ByteString -> PreSharedKeyIDCore
ExternalKeyID (ByteString -> PreSharedKeyIDCore)
-> Get ByteString -> Get PreSharedKeyIDCore
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall w. (Binary w, Integral w) => Get ByteString
parseMLSBytes @VarInt
      PreSharedKeyTag
ResumptionKeyTag -> Resumption -> PreSharedKeyIDCore
ResumptionKeyID (Resumption -> PreSharedKeyIDCore)
-> Get Resumption -> Get PreSharedKeyIDCore
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Resumption
forall a. ParseMLS a => Get a
parseMLS

instance SerialiseMLS PreSharedKeyIDCore where
  serialiseMLS :: PreSharedKeyIDCore -> Put
serialiseMLS (ExternalKeyID ByteString
bs) = do
    PreSharedKeyTag -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS PreSharedKeyTag
ExternalKeyTag
    forall w. (Binary w, Integral w) => ByteString -> Put
serialiseMLSBytes @VarInt ByteString
bs
  serialiseMLS (ResumptionKeyID Resumption
r) = do
    PreSharedKeyTag -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS PreSharedKeyTag
ResumptionKeyTag
    Resumption -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS Resumption
r

data PreSharedKeyID = PreSharedKeyID
  { PreSharedKeyID -> PreSharedKeyIDCore
core :: PreSharedKeyIDCore,
    PreSharedKeyID -> ByteString
nonce :: ByteString
  }
  deriving stock (PreSharedKeyID -> PreSharedKeyID -> Bool
(PreSharedKeyID -> PreSharedKeyID -> Bool)
-> (PreSharedKeyID -> PreSharedKeyID -> Bool) -> Eq PreSharedKeyID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PreSharedKeyID -> PreSharedKeyID -> Bool
== :: PreSharedKeyID -> PreSharedKeyID -> Bool
$c/= :: PreSharedKeyID -> PreSharedKeyID -> Bool
/= :: PreSharedKeyID -> PreSharedKeyID -> Bool
Eq, Int -> PreSharedKeyID -> ShowS
[PreSharedKeyID] -> ShowS
PreSharedKeyID -> String
(Int -> PreSharedKeyID -> ShowS)
-> (PreSharedKeyID -> String)
-> ([PreSharedKeyID] -> ShowS)
-> Show PreSharedKeyID
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PreSharedKeyID -> ShowS
showsPrec :: Int -> PreSharedKeyID -> ShowS
$cshow :: PreSharedKeyID -> String
show :: PreSharedKeyID -> String
$cshowList :: [PreSharedKeyID] -> ShowS
showList :: [PreSharedKeyID] -> ShowS
Show, (forall x. PreSharedKeyID -> Rep PreSharedKeyID x)
-> (forall x. Rep PreSharedKeyID x -> PreSharedKeyID)
-> Generic PreSharedKeyID
forall x. Rep PreSharedKeyID x -> PreSharedKeyID
forall x. PreSharedKeyID -> Rep PreSharedKeyID x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. PreSharedKeyID -> Rep PreSharedKeyID x
from :: forall x. PreSharedKeyID -> Rep PreSharedKeyID x
$cto :: forall x. Rep PreSharedKeyID x -> PreSharedKeyID
to :: forall x. Rep PreSharedKeyID x -> PreSharedKeyID
Generic)
  deriving (Gen PreSharedKeyID
Gen PreSharedKeyID
-> (PreSharedKeyID -> [PreSharedKeyID]) -> Arbitrary PreSharedKeyID
PreSharedKeyID -> [PreSharedKeyID]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen PreSharedKeyID
arbitrary :: Gen PreSharedKeyID
$cshrink :: PreSharedKeyID -> [PreSharedKeyID]
shrink :: PreSharedKeyID -> [PreSharedKeyID]
Arbitrary) via (GenericUniform PreSharedKeyID)

instance ParseMLS PreSharedKeyID where
  parseMLS :: Get PreSharedKeyID
parseMLS = PreSharedKeyIDCore -> ByteString -> PreSharedKeyID
PreSharedKeyID (PreSharedKeyIDCore -> ByteString -> PreSharedKeyID)
-> Get PreSharedKeyIDCore -> Get (ByteString -> PreSharedKeyID)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get PreSharedKeyIDCore
forall a. ParseMLS a => Get a
parseMLS Get (ByteString -> PreSharedKeyID)
-> Get ByteString -> Get PreSharedKeyID
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall w. (Binary w, Integral w) => Get ByteString
parseMLSBytes @VarInt

instance SerialiseMLS PreSharedKeyID where
  serialiseMLS :: PreSharedKeyID -> Put
serialiseMLS PreSharedKeyID
psk = do
    PreSharedKeyIDCore -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS PreSharedKeyID
psk.core
    forall w. (Binary w, Integral w) => ByteString -> Put
serialiseMLSBytes @VarInt PreSharedKeyID
psk.nonce

-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-8.4-6
data Resumption = Resumption
  { Resumption -> Word8
usage :: Word8,
    Resumption -> GroupId
groupId :: GroupId,
    Resumption -> Word64
epoch :: Word64
  }
  deriving stock (Resumption -> Resumption -> Bool
(Resumption -> Resumption -> Bool)
-> (Resumption -> Resumption -> Bool) -> Eq Resumption
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Resumption -> Resumption -> Bool
== :: Resumption -> Resumption -> Bool
$c/= :: Resumption -> Resumption -> Bool
/= :: Resumption -> Resumption -> Bool
Eq, Int -> Resumption -> ShowS
[Resumption] -> ShowS
Resumption -> String
(Int -> Resumption -> ShowS)
-> (Resumption -> String)
-> ([Resumption] -> ShowS)
-> Show Resumption
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Resumption -> ShowS
showsPrec :: Int -> Resumption -> ShowS
$cshow :: Resumption -> String
show :: Resumption -> String
$cshowList :: [Resumption] -> ShowS
showList :: [Resumption] -> ShowS
Show, (forall x. Resumption -> Rep Resumption x)
-> (forall x. Rep Resumption x -> Resumption) -> Generic Resumption
forall x. Rep Resumption x -> Resumption
forall x. Resumption -> Rep Resumption x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Resumption -> Rep Resumption x
from :: forall x. Resumption -> Rep Resumption x
$cto :: forall x. Rep Resumption x -> Resumption
to :: forall x. Rep Resumption x -> Resumption
Generic)
  deriving (Gen Resumption
Gen Resumption
-> (Resumption -> [Resumption]) -> Arbitrary Resumption
Resumption -> [Resumption]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen Resumption
arbitrary :: Gen Resumption
$cshrink :: Resumption -> [Resumption]
shrink :: Resumption -> [Resumption]
Arbitrary) via (GenericUniform Resumption)

instance ParseMLS Resumption where
  parseMLS :: Get Resumption
parseMLS =
    Word8 -> GroupId -> Word64 -> Resumption
Resumption
      (Word8 -> GroupId -> Word64 -> Resumption)
-> Get Word8 -> Get (GroupId -> Word64 -> Resumption)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word8
forall a. ParseMLS a => Get a
parseMLS
      Get (GroupId -> Word64 -> Resumption)
-> Get GroupId -> Get (Word64 -> Resumption)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get GroupId
forall a. ParseMLS a => Get a
parseMLS
      Get (Word64 -> Resumption) -> Get Word64 -> Get Resumption
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get Word64
forall a. ParseMLS a => Get a
parseMLS

instance SerialiseMLS Resumption where
  serialiseMLS :: Resumption -> Put
serialiseMLS Resumption
r = do
    Word8 -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS Resumption
r.usage
    GroupId -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS Resumption
r.groupId
    Word64 -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS Resumption
r.epoch

-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-12.1.5-2
data ReInit = ReInit
  { ReInit -> GroupId
groupId :: GroupId,
    ReInit -> ProtocolVersion
protocolVersion :: ProtocolVersion,
    ReInit -> CipherSuite
cipherSuite :: CipherSuite,
    ReInit -> [Extension]
extensions :: [Extension]
  }
  deriving stock (ReInit -> ReInit -> Bool
(ReInit -> ReInit -> Bool)
-> (ReInit -> ReInit -> Bool) -> Eq ReInit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ReInit -> ReInit -> Bool
== :: ReInit -> ReInit -> Bool
$c/= :: ReInit -> ReInit -> Bool
/= :: ReInit -> ReInit -> Bool
Eq, Int -> ReInit -> ShowS
[ReInit] -> ShowS
ReInit -> String
(Int -> ReInit -> ShowS)
-> (ReInit -> String) -> ([ReInit] -> ShowS) -> Show ReInit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ReInit -> ShowS
showsPrec :: Int -> ReInit -> ShowS
$cshow :: ReInit -> String
show :: ReInit -> String
$cshowList :: [ReInit] -> ShowS
showList :: [ReInit] -> ShowS
Show, (forall x. ReInit -> Rep ReInit x)
-> (forall x. Rep ReInit x -> ReInit) -> Generic ReInit
forall x. Rep ReInit x -> ReInit
forall x. ReInit -> Rep ReInit x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ReInit -> Rep ReInit x
from :: forall x. ReInit -> Rep ReInit x
$cto :: forall x. Rep ReInit x -> ReInit
to :: forall x. Rep ReInit x -> ReInit
Generic)
  deriving (Gen ReInit
Gen ReInit -> (ReInit -> [ReInit]) -> Arbitrary ReInit
ReInit -> [ReInit]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen ReInit
arbitrary :: Gen ReInit
$cshrink :: ReInit -> [ReInit]
shrink :: ReInit -> [ReInit]
Arbitrary) via (GenericUniform ReInit)

instance ParseMLS ReInit where
  parseMLS :: Get ReInit
parseMLS =
    GroupId -> ProtocolVersion -> CipherSuite -> [Extension] -> ReInit
ReInit
      (GroupId
 -> ProtocolVersion -> CipherSuite -> [Extension] -> ReInit)
-> Get GroupId
-> Get (ProtocolVersion -> CipherSuite -> [Extension] -> ReInit)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get GroupId
forall a. ParseMLS a => Get a
parseMLS
      Get (ProtocolVersion -> CipherSuite -> [Extension] -> ReInit)
-> Get ProtocolVersion
-> Get (CipherSuite -> [Extension] -> ReInit)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get ProtocolVersion
forall a. ParseMLS a => Get a
parseMLS
      Get (CipherSuite -> [Extension] -> ReInit)
-> Get CipherSuite -> Get ([Extension] -> ReInit)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get CipherSuite
forall a. ParseMLS a => Get a
parseMLS
      Get ([Extension] -> ReInit) -> Get [Extension] -> Get ReInit
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall w a. (Binary w, Integral w) => Get a -> Get [a]
parseMLSVector @VarInt Get Extension
forall a. ParseMLS a => Get a
parseMLS

instance SerialiseMLS ReInit where
  serialiseMLS :: ReInit -> Put
serialiseMLS ReInit
ri = do
    GroupId -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ReInit
ri.groupId
    ProtocolVersion -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ReInit
ri.protocolVersion
    CipherSuite -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ReInit
ri.cipherSuite
    forall w a. (Binary w, Integral w) => (a -> Put) -> [a] -> Put
serialiseMLSVector @VarInt Extension -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ReInit
ri.extensions

data MessageRange = MessageRange
  { MessageRange -> KeyPackageRef
sender :: KeyPackageRef,
    MessageRange -> LeafIndex
firstGeneration :: Word32,
    MessageRange -> LeafIndex
lastGeneration :: Word32
  }
  deriving stock (MessageRange -> MessageRange -> Bool
(MessageRange -> MessageRange -> Bool)
-> (MessageRange -> MessageRange -> Bool) -> Eq MessageRange
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MessageRange -> MessageRange -> Bool
== :: MessageRange -> MessageRange -> Bool
$c/= :: MessageRange -> MessageRange -> Bool
/= :: MessageRange -> MessageRange -> Bool
Eq, Int -> MessageRange -> ShowS
[MessageRange] -> ShowS
MessageRange -> String
(Int -> MessageRange -> ShowS)
-> (MessageRange -> String)
-> ([MessageRange] -> ShowS)
-> Show MessageRange
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MessageRange -> ShowS
showsPrec :: Int -> MessageRange -> ShowS
$cshow :: MessageRange -> String
show :: MessageRange -> String
$cshowList :: [MessageRange] -> ShowS
showList :: [MessageRange] -> ShowS
Show)

instance Arbitrary MessageRange where
  arbitrary :: Gen MessageRange
arbitrary = KeyPackageRef -> LeafIndex -> LeafIndex -> MessageRange
MessageRange (KeyPackageRef -> LeafIndex -> LeafIndex -> MessageRange)
-> Gen KeyPackageRef
-> Gen (LeafIndex -> LeafIndex -> MessageRange)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen KeyPackageRef
forall a. Arbitrary a => Gen a
arbitrary Gen (LeafIndex -> LeafIndex -> MessageRange)
-> Gen LeafIndex -> Gen (LeafIndex -> MessageRange)
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen LeafIndex
forall a. Arbitrary a => Gen a
arbitrary Gen (LeafIndex -> MessageRange)
-> Gen LeafIndex -> Gen MessageRange
forall a b. Gen (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen LeafIndex
forall a. Arbitrary a => Gen a
arbitrary

instance ParseMLS MessageRange where
  parseMLS :: Get MessageRange
parseMLS =
    KeyPackageRef -> LeafIndex -> LeafIndex -> MessageRange
MessageRange
      (KeyPackageRef -> LeafIndex -> LeafIndex -> MessageRange)
-> Get KeyPackageRef
-> Get (LeafIndex -> LeafIndex -> MessageRange)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get KeyPackageRef
forall a. ParseMLS a => Get a
parseMLS
      Get (LeafIndex -> LeafIndex -> MessageRange)
-> Get LeafIndex -> Get (LeafIndex -> MessageRange)
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get LeafIndex
forall a. ParseMLS a => Get a
parseMLS
      Get (LeafIndex -> MessageRange)
-> Get LeafIndex -> Get MessageRange
forall a b. Get (a -> b) -> Get a -> Get b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get LeafIndex
forall a. ParseMLS a => Get a
parseMLS

instance SerialiseMLS MessageRange where
  serialiseMLS :: MessageRange -> Put
serialiseMLS MessageRange {LeafIndex
KeyPackageRef
$sel:sender:MessageRange :: MessageRange -> KeyPackageRef
$sel:firstGeneration:MessageRange :: MessageRange -> LeafIndex
$sel:lastGeneration:MessageRange :: MessageRange -> LeafIndex
sender :: KeyPackageRef
firstGeneration :: LeafIndex
lastGeneration :: LeafIndex
..} = do
    KeyPackageRef -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS KeyPackageRef
sender
    LeafIndex -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS LeafIndex
firstGeneration
    LeafIndex -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS LeafIndex
lastGeneration

-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-12.4-3
data ProposalOrRefTag = InlineTag | RefTag
  deriving stock (ProposalOrRefTag
ProposalOrRefTag -> ProposalOrRefTag -> Bounded ProposalOrRefTag
forall a. a -> a -> Bounded a
$cminBound :: ProposalOrRefTag
minBound :: ProposalOrRefTag
$cmaxBound :: ProposalOrRefTag
maxBound :: ProposalOrRefTag
Bounded, Int -> ProposalOrRefTag
ProposalOrRefTag -> Int
ProposalOrRefTag -> [ProposalOrRefTag]
ProposalOrRefTag -> ProposalOrRefTag
ProposalOrRefTag -> ProposalOrRefTag -> [ProposalOrRefTag]
ProposalOrRefTag
-> ProposalOrRefTag -> ProposalOrRefTag -> [ProposalOrRefTag]
(ProposalOrRefTag -> ProposalOrRefTag)
-> (ProposalOrRefTag -> ProposalOrRefTag)
-> (Int -> ProposalOrRefTag)
-> (ProposalOrRefTag -> Int)
-> (ProposalOrRefTag -> [ProposalOrRefTag])
-> (ProposalOrRefTag -> ProposalOrRefTag -> [ProposalOrRefTag])
-> (ProposalOrRefTag -> ProposalOrRefTag -> [ProposalOrRefTag])
-> (ProposalOrRefTag
    -> ProposalOrRefTag -> ProposalOrRefTag -> [ProposalOrRefTag])
-> Enum ProposalOrRefTag
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: ProposalOrRefTag -> ProposalOrRefTag
succ :: ProposalOrRefTag -> ProposalOrRefTag
$cpred :: ProposalOrRefTag -> ProposalOrRefTag
pred :: ProposalOrRefTag -> ProposalOrRefTag
$ctoEnum :: Int -> ProposalOrRefTag
toEnum :: Int -> ProposalOrRefTag
$cfromEnum :: ProposalOrRefTag -> Int
fromEnum :: ProposalOrRefTag -> Int
$cenumFrom :: ProposalOrRefTag -> [ProposalOrRefTag]
enumFrom :: ProposalOrRefTag -> [ProposalOrRefTag]
$cenumFromThen :: ProposalOrRefTag -> ProposalOrRefTag -> [ProposalOrRefTag]
enumFromThen :: ProposalOrRefTag -> ProposalOrRefTag -> [ProposalOrRefTag]
$cenumFromTo :: ProposalOrRefTag -> ProposalOrRefTag -> [ProposalOrRefTag]
enumFromTo :: ProposalOrRefTag -> ProposalOrRefTag -> [ProposalOrRefTag]
$cenumFromThenTo :: ProposalOrRefTag
-> ProposalOrRefTag -> ProposalOrRefTag -> [ProposalOrRefTag]
enumFromThenTo :: ProposalOrRefTag
-> ProposalOrRefTag -> ProposalOrRefTag -> [ProposalOrRefTag]
Enum, ProposalOrRefTag -> ProposalOrRefTag -> Bool
(ProposalOrRefTag -> ProposalOrRefTag -> Bool)
-> (ProposalOrRefTag -> ProposalOrRefTag -> Bool)
-> Eq ProposalOrRefTag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ProposalOrRefTag -> ProposalOrRefTag -> Bool
== :: ProposalOrRefTag -> ProposalOrRefTag -> Bool
$c/= :: ProposalOrRefTag -> ProposalOrRefTag -> Bool
/= :: ProposalOrRefTag -> ProposalOrRefTag -> Bool
Eq, Int -> ProposalOrRefTag -> ShowS
[ProposalOrRefTag] -> ShowS
ProposalOrRefTag -> String
(Int -> ProposalOrRefTag -> ShowS)
-> (ProposalOrRefTag -> String)
-> ([ProposalOrRefTag] -> ShowS)
-> Show ProposalOrRefTag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ProposalOrRefTag -> ShowS
showsPrec :: Int -> ProposalOrRefTag -> ShowS
$cshow :: ProposalOrRefTag -> String
show :: ProposalOrRefTag -> String
$cshowList :: [ProposalOrRefTag] -> ShowS
showList :: [ProposalOrRefTag] -> ShowS
Show)

instance ParseMLS ProposalOrRefTag where
  parseMLS :: Get ProposalOrRefTag
parseMLS = forall w a.
(Bounded a, Enum a, Integral w, Binary w) =>
String -> Get a
parseMLSEnum @Word8 String
"ProposalOrRef type"

instance SerialiseMLS ProposalOrRefTag where
  serialiseMLS :: ProposalOrRefTag -> Put
serialiseMLS = forall w a. (Enum a, Integral w, Binary w) => a -> Put
serialiseMLSEnum @Word8

-- | https://messaginglayersecurity.rocks/mls-protocol/draft-ietf-mls-protocol-20/draft-ietf-mls-protocol.html#section-12.4-3
data ProposalOrRef = Inline Proposal | Ref ProposalRef
  deriving stock (ProposalOrRef -> ProposalOrRef -> Bool
(ProposalOrRef -> ProposalOrRef -> Bool)
-> (ProposalOrRef -> ProposalOrRef -> Bool) -> Eq ProposalOrRef
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ProposalOrRef -> ProposalOrRef -> Bool
== :: ProposalOrRef -> ProposalOrRef -> Bool
$c/= :: ProposalOrRef -> ProposalOrRef -> Bool
/= :: ProposalOrRef -> ProposalOrRef -> Bool
Eq, Int -> ProposalOrRef -> ShowS
[ProposalOrRef] -> ShowS
ProposalOrRef -> String
(Int -> ProposalOrRef -> ShowS)
-> (ProposalOrRef -> String)
-> ([ProposalOrRef] -> ShowS)
-> Show ProposalOrRef
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ProposalOrRef -> ShowS
showsPrec :: Int -> ProposalOrRef -> ShowS
$cshow :: ProposalOrRef -> String
show :: ProposalOrRef -> String
$cshowList :: [ProposalOrRef] -> ShowS
showList :: [ProposalOrRef] -> ShowS
Show, (forall x. ProposalOrRef -> Rep ProposalOrRef x)
-> (forall x. Rep ProposalOrRef x -> ProposalOrRef)
-> Generic ProposalOrRef
forall x. Rep ProposalOrRef x -> ProposalOrRef
forall x. ProposalOrRef -> Rep ProposalOrRef x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ProposalOrRef -> Rep ProposalOrRef x
from :: forall x. ProposalOrRef -> Rep ProposalOrRef x
$cto :: forall x. Rep ProposalOrRef x -> ProposalOrRef
to :: forall x. Rep ProposalOrRef x -> ProposalOrRef
Generic)
  deriving (Gen ProposalOrRef
Gen ProposalOrRef
-> (ProposalOrRef -> [ProposalOrRef]) -> Arbitrary ProposalOrRef
ProposalOrRef -> [ProposalOrRef]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen ProposalOrRef
arbitrary :: Gen ProposalOrRef
$cshrink :: ProposalOrRef -> [ProposalOrRef]
shrink :: ProposalOrRef -> [ProposalOrRef]
Arbitrary) via (GenericUniform ProposalOrRef)

instance ParseMLS ProposalOrRef where
  parseMLS :: Get ProposalOrRef
parseMLS =
    Get ProposalOrRefTag
forall a. ParseMLS a => Get a
parseMLS Get ProposalOrRefTag
-> (ProposalOrRefTag -> Get ProposalOrRef) -> Get ProposalOrRef
forall a b. Get a -> (a -> Get b) -> Get b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      ProposalOrRefTag
InlineTag -> Proposal -> ProposalOrRef
Inline (Proposal -> ProposalOrRef) -> Get Proposal -> Get ProposalOrRef
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Proposal
forall a. ParseMLS a => Get a
parseMLS
      ProposalOrRefTag
RefTag -> ProposalRef -> ProposalOrRef
Ref (ProposalRef -> ProposalOrRef)
-> Get ProposalRef -> Get ProposalOrRef
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get ProposalRef
forall a. ParseMLS a => Get a
parseMLS

instance SerialiseMLS ProposalOrRef where
  serialiseMLS :: ProposalOrRef -> Put
serialiseMLS (Inline Proposal
p) = do
    ProposalOrRefTag -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ProposalOrRefTag
InlineTag
    Proposal -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS Proposal
p
  serialiseMLS (Ref ProposalRef
r) = do
    ProposalOrRefTag -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ProposalOrRefTag
RefTag
    ProposalRef -> Put
forall a. SerialiseMLS a => a -> Put
serialiseMLS ProposalRef
r

newtype ProposalRef = ProposalRef {ProposalRef -> ByteString
unProposalRef :: ByteString}
  deriving stock (ProposalRef -> ProposalRef -> Bool
(ProposalRef -> ProposalRef -> Bool)
-> (ProposalRef -> ProposalRef -> Bool) -> Eq ProposalRef
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ProposalRef -> ProposalRef -> Bool
== :: ProposalRef -> ProposalRef -> Bool
$c/= :: ProposalRef -> ProposalRef -> Bool
/= :: ProposalRef -> ProposalRef -> Bool
Eq, Int -> ProposalRef -> ShowS
[ProposalRef] -> ShowS
ProposalRef -> String
(Int -> ProposalRef -> ShowS)
-> (ProposalRef -> String)
-> ([ProposalRef] -> ShowS)
-> Show ProposalRef
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ProposalRef -> ShowS
showsPrec :: Int -> ProposalRef -> ShowS
$cshow :: ProposalRef -> String
show :: ProposalRef -> String
$cshowList :: [ProposalRef] -> ShowS
showList :: [ProposalRef] -> ShowS
Show, Eq ProposalRef
Eq ProposalRef =>
(ProposalRef -> ProposalRef -> Ordering)
-> (ProposalRef -> ProposalRef -> Bool)
-> (ProposalRef -> ProposalRef -> Bool)
-> (ProposalRef -> ProposalRef -> Bool)
-> (ProposalRef -> ProposalRef -> Bool)
-> (ProposalRef -> ProposalRef -> ProposalRef)
-> (ProposalRef -> ProposalRef -> ProposalRef)
-> Ord ProposalRef
ProposalRef -> ProposalRef -> Bool
ProposalRef -> ProposalRef -> Ordering
ProposalRef -> ProposalRef -> ProposalRef
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
$ccompare :: ProposalRef -> ProposalRef -> Ordering
compare :: ProposalRef -> ProposalRef -> Ordering
$c< :: ProposalRef -> ProposalRef -> Bool
< :: ProposalRef -> ProposalRef -> Bool
$c<= :: ProposalRef -> ProposalRef -> Bool
<= :: ProposalRef -> ProposalRef -> Bool
$c> :: ProposalRef -> ProposalRef -> Bool
> :: ProposalRef -> ProposalRef -> Bool
$c>= :: ProposalRef -> ProposalRef -> Bool
>= :: ProposalRef -> ProposalRef -> Bool
$cmax :: ProposalRef -> ProposalRef -> ProposalRef
max :: ProposalRef -> ProposalRef -> ProposalRef
$cmin :: ProposalRef -> ProposalRef -> ProposalRef
min :: ProposalRef -> ProposalRef -> ProposalRef
Ord, (forall x. ProposalRef -> Rep ProposalRef x)
-> (forall x. Rep ProposalRef x -> ProposalRef)
-> Generic ProposalRef
forall x. Rep ProposalRef x -> ProposalRef
forall x. ProposalRef -> Rep ProposalRef x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ProposalRef -> Rep ProposalRef x
from :: forall x. ProposalRef -> Rep ProposalRef x
$cto :: forall x. Rep ProposalRef x -> ProposalRef
to :: forall x. Rep ProposalRef x -> ProposalRef
Generic)
  deriving newtype (Gen ProposalRef
Gen ProposalRef
-> (ProposalRef -> [ProposalRef]) -> Arbitrary ProposalRef
ProposalRef -> [ProposalRef]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
$carbitrary :: Gen ProposalRef
arbitrary :: Gen ProposalRef
$cshrink :: ProposalRef -> [ProposalRef]
shrink :: ProposalRef -> [ProposalRef]
Arbitrary)

instance ParseMLS ProposalRef where
  parseMLS :: Get ProposalRef
parseMLS = ByteString -> ProposalRef
ProposalRef (ByteString -> ProposalRef) -> Get ByteString -> Get ProposalRef
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall w. (Binary w, Integral w) => Get ByteString
parseMLSBytes @VarInt

instance SerialiseMLS ProposalRef where
  serialiseMLS :: ProposalRef -> Put
serialiseMLS = forall w. (Binary w, Integral w) => ByteString -> Put
serialiseMLSBytes @VarInt (ByteString -> Put)
-> (ProposalRef -> ByteString) -> ProposalRef -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProposalRef -> ByteString
unProposalRef

makePrisms ''ProposalOrRef

data ProposalOrigin
  = ProposalOriginClient
  | ProposalOriginBackend
  deriving (ProposalOrigin -> ProposalOrigin -> Bool
(ProposalOrigin -> ProposalOrigin -> Bool)
-> (ProposalOrigin -> ProposalOrigin -> Bool) -> Eq ProposalOrigin
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ProposalOrigin -> ProposalOrigin -> Bool
== :: ProposalOrigin -> ProposalOrigin -> Bool
$c/= :: ProposalOrigin -> ProposalOrigin -> Bool
/= :: ProposalOrigin -> ProposalOrigin -> Bool
Eq)

instance Cql ProposalOrigin where
  ctype :: Tagged ProposalOrigin ColumnType
ctype = ColumnType -> Tagged ProposalOrigin ColumnType
forall a b. b -> Tagged a b
Tagged ColumnType
IntColumn
  toCql :: ProposalOrigin -> Value
toCql = Int32 -> Value
CqlInt (Int32 -> Value)
-> (ProposalOrigin -> Int32) -> ProposalOrigin -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ProposalOrigin -> Int32
originToInt
  fromCql :: Value -> Either String ProposalOrigin
fromCql (CqlInt Int32
i) = Int32 -> Either String ProposalOrigin
intToOrigin Int32
i
  fromCql Value
_ = String -> Either String ProposalOrigin
forall a b. a -> Either a b
Left String
"intToOrigin: unexptected data"

originToInt :: ProposalOrigin -> Int32
originToInt :: ProposalOrigin -> Int32
originToInt ProposalOrigin
ProposalOriginClient = Int32
0
originToInt ProposalOrigin
ProposalOriginBackend = Int32
1

intToOrigin :: Int32 -> Either String ProposalOrigin
intToOrigin :: Int32 -> Either String ProposalOrigin
intToOrigin Int32
0 = ProposalOrigin -> Either String ProposalOrigin
forall a. a -> Either String a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ProposalOrigin
ProposalOriginClient
intToOrigin Int32
1 = ProposalOrigin -> Either String ProposalOrigin
forall a. a -> Either String a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ProposalOrigin
ProposalOriginBackend
intToOrigin Int32
n = String -> Either String ProposalOrigin
forall a b. a -> Either a b
Left (String -> Either String ProposalOrigin)
-> String -> Either String ProposalOrigin
forall a b. (a -> b) -> a -> b
$ String
"intToOrigin: unexptected int constant: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int32 -> String
forall a. Show a => a -> String
show Int32
n