{-# OPTIONS_HADDOCK prune #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}

-- |
-- Module: Lightning.Protocol.BOLT1.Message
-- Copyright: (c) 2025 Jared Tobin
-- License: MIT
-- Maintainer: Jared Tobin <jared@ppad.tech>
--
-- Message types for BOLT #1.

module Lightning.Protocol.BOLT1.Message (
  -- * Message types
    MsgType(..)
  , msgTypeWord
  , parseMsgType

  -- * Channel identifiers
  , ChannelId
  , channelId
  , unChannelId
  , allChannels

  -- * Setup messages
  , Init(..)
  , Error(..)
  , Warning(..)

  -- * Control messages
  , Ping(..)
  , Pong(..)

  -- * Peer storage messages
  , PeerStorage(..)
  , PeerStorageRetrieval(..)

  -- * Message envelope
  , Message(..)
  , messageType
  , Envelope(..)
  ) where

import Control.DeepSeq (NFData)
import qualified Data.ByteString as BS
import Data.Word (Word16)
import GHC.Generics (Generic)
import Lightning.Protocol.BOLT1.TLV

-- Message types ---------------------------------------------------------------

-- | BOLT #1 message type codes.
data MsgType
  = MsgInit              -- ^ 16
  | MsgError             -- ^ 17
  | MsgPing              -- ^ 18
  | MsgPong              -- ^ 19
  | MsgWarning           -- ^ 1
  | MsgPeerStorage       -- ^ 7
  | MsgPeerStorageRet    -- ^ 9
  | MsgUnknown !Word16   -- ^ Unknown type
  deriving stock (MsgType -> MsgType -> Bool
(MsgType -> MsgType -> Bool)
-> (MsgType -> MsgType -> Bool) -> Eq MsgType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MsgType -> MsgType -> Bool
== :: MsgType -> MsgType -> Bool
$c/= :: MsgType -> MsgType -> Bool
/= :: MsgType -> MsgType -> Bool
Eq, Int -> MsgType -> ShowS
[MsgType] -> ShowS
MsgType -> String
(Int -> MsgType -> ShowS)
-> (MsgType -> String) -> ([MsgType] -> ShowS) -> Show MsgType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MsgType -> ShowS
showsPrec :: Int -> MsgType -> ShowS
$cshow :: MsgType -> String
show :: MsgType -> String
$cshowList :: [MsgType] -> ShowS
showList :: [MsgType] -> ShowS
Show, (forall x. MsgType -> Rep MsgType x)
-> (forall x. Rep MsgType x -> MsgType) -> Generic MsgType
forall x. Rep MsgType x -> MsgType
forall x. MsgType -> Rep MsgType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. MsgType -> Rep MsgType x
from :: forall x. MsgType -> Rep MsgType x
$cto :: forall x. Rep MsgType x -> MsgType
to :: forall x. Rep MsgType x -> MsgType
Generic)

instance NFData MsgType

-- | Get the numeric type code for a message type.
msgTypeWord :: MsgType -> Word16
msgTypeWord :: MsgType -> Word16
msgTypeWord MsgType
MsgInit            = Word16
16
msgTypeWord MsgType
MsgError           = Word16
17
msgTypeWord MsgType
MsgPing            = Word16
18
msgTypeWord MsgType
MsgPong            = Word16
19
msgTypeWord MsgType
MsgWarning         = Word16
1
msgTypeWord MsgType
MsgPeerStorage     = Word16
7
msgTypeWord MsgType
MsgPeerStorageRet  = Word16
9
msgTypeWord (MsgUnknown Word16
w)     = Word16
w

-- | Parse a message type from a word.
parseMsgType :: Word16 -> MsgType
parseMsgType :: Word16 -> MsgType
parseMsgType Word16
16 = MsgType
MsgInit
parseMsgType Word16
17 = MsgType
MsgError
parseMsgType Word16
18 = MsgType
MsgPing
parseMsgType Word16
19 = MsgType
MsgPong
parseMsgType Word16
1  = MsgType
MsgWarning
parseMsgType Word16
7  = MsgType
MsgPeerStorage
parseMsgType Word16
9  = MsgType
MsgPeerStorageRet
parseMsgType Word16
w  = Word16 -> MsgType
MsgUnknown Word16
w

-- Channel identifiers ---------------------------------------------------------

-- | A 32-byte channel identifier.
--
-- Use 'channelId' to construct, which validates the length.
-- Use 'allChannels' for connection-level errors (all-zeros channel ID).
newtype ChannelId = ChannelId BS.ByteString
  deriving stock (ChannelId -> ChannelId -> Bool
(ChannelId -> ChannelId -> Bool)
-> (ChannelId -> ChannelId -> Bool) -> Eq ChannelId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ChannelId -> ChannelId -> Bool
== :: ChannelId -> ChannelId -> Bool
$c/= :: ChannelId -> ChannelId -> Bool
/= :: ChannelId -> ChannelId -> Bool
Eq, Int -> ChannelId -> ShowS
[ChannelId] -> ShowS
ChannelId -> String
(Int -> ChannelId -> ShowS)
-> (ChannelId -> String)
-> ([ChannelId] -> ShowS)
-> Show ChannelId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ChannelId -> ShowS
showsPrec :: Int -> ChannelId -> ShowS
$cshow :: ChannelId -> String
show :: ChannelId -> String
$cshowList :: [ChannelId] -> ShowS
showList :: [ChannelId] -> ShowS
Show, (forall x. ChannelId -> Rep ChannelId x)
-> (forall x. Rep ChannelId x -> ChannelId) -> Generic ChannelId
forall x. Rep ChannelId x -> ChannelId
forall x. ChannelId -> Rep ChannelId x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. ChannelId -> Rep ChannelId x
from :: forall x. ChannelId -> Rep ChannelId x
$cto :: forall x. Rep ChannelId x -> ChannelId
to :: forall x. Rep ChannelId x -> ChannelId
Generic)

instance NFData ChannelId

-- | Construct a 'ChannelId' from a 32-byte 'BS.ByteString'.
--
-- Returns 'Nothing' if the input is not exactly 32 bytes.
--
-- >>> channelId (BS.replicate 32 0x00)
-- Just (ChannelId "\NUL\NUL...")
-- >>> channelId "too short"
-- Nothing
channelId :: BS.ByteString -> Maybe ChannelId
channelId :: ByteString -> Maybe ChannelId
channelId ByteString
bs
  | ByteString -> Int
BS.length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
32 = ChannelId -> Maybe ChannelId
forall a. a -> Maybe a
Just (ByteString -> ChannelId
ChannelId ByteString
bs)
  | Bool
otherwise          = Maybe ChannelId
forall a. Maybe a
Nothing
{-# INLINE channelId #-}

-- | The all-zeros channel ID, used for connection-level errors.
--
-- Per BOLT #1, setting channel_id to all zeros means the error applies
-- to the connection rather than a specific channel.
allChannels :: ChannelId
allChannels :: ChannelId
allChannels = ByteString -> ChannelId
ChannelId (Int -> Word8 -> ByteString
BS.replicate Int
32 Word8
0x00)

-- | Extract the raw bytes from a 'ChannelId'.
unChannelId :: ChannelId -> BS.ByteString
unChannelId :: ChannelId -> ByteString
unChannelId (ChannelId ByteString
bs) = ByteString
bs
{-# INLINE unChannelId #-}

-- Message ADTs ----------------------------------------------------------------

-- | The init message (type 16).
data Init = Init
  { Init -> ByteString
initGlobalFeatures :: !BS.ByteString
  , Init -> ByteString
initFeatures       :: !BS.ByteString
  , Init -> [InitTlv]
initTlvs           :: ![InitTlv]
  } deriving stock (Init -> Init -> Bool
(Init -> Init -> Bool) -> (Init -> Init -> Bool) -> Eq Init
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Init -> Init -> Bool
== :: Init -> Init -> Bool
$c/= :: Init -> Init -> Bool
/= :: Init -> Init -> Bool
Eq, Int -> Init -> ShowS
[Init] -> ShowS
Init -> String
(Int -> Init -> ShowS)
-> (Init -> String) -> ([Init] -> ShowS) -> Show Init
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Init -> ShowS
showsPrec :: Int -> Init -> ShowS
$cshow :: Init -> String
show :: Init -> String
$cshowList :: [Init] -> ShowS
showList :: [Init] -> ShowS
Show, (forall x. Init -> Rep Init x)
-> (forall x. Rep Init x -> Init) -> Generic Init
forall x. Rep Init x -> Init
forall x. Init -> Rep Init x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Init -> Rep Init x
from :: forall x. Init -> Rep Init x
$cto :: forall x. Rep Init x -> Init
to :: forall x. Rep Init x -> Init
Generic)

instance NFData Init

-- | The error message (type 17).
data Error = Error
  { Error -> ChannelId
errorChannelId :: !ChannelId
  , Error -> ByteString
errorData      :: !BS.ByteString
  } deriving stock (Error -> Error -> Bool
(Error -> Error -> Bool) -> (Error -> Error -> Bool) -> Eq Error
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Error -> Error -> Bool
== :: Error -> Error -> Bool
$c/= :: Error -> Error -> Bool
/= :: Error -> Error -> Bool
Eq, Int -> Error -> ShowS
[Error] -> ShowS
Error -> String
(Int -> Error -> ShowS)
-> (Error -> String) -> ([Error] -> ShowS) -> Show Error
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Error -> ShowS
showsPrec :: Int -> Error -> ShowS
$cshow :: Error -> String
show :: Error -> String
$cshowList :: [Error] -> ShowS
showList :: [Error] -> ShowS
Show, (forall x. Error -> Rep Error x)
-> (forall x. Rep Error x -> Error) -> Generic Error
forall x. Rep Error x -> Error
forall x. Error -> Rep Error x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Error -> Rep Error x
from :: forall x. Error -> Rep Error x
$cto :: forall x. Rep Error x -> Error
to :: forall x. Rep Error x -> Error
Generic)

instance NFData Error

-- | The warning message (type 1).
data Warning = Warning
  { Warning -> ChannelId
warningChannelId :: !ChannelId
  , Warning -> ByteString
warningData      :: !BS.ByteString
  } deriving stock (Warning -> Warning -> Bool
(Warning -> Warning -> Bool)
-> (Warning -> Warning -> Bool) -> Eq Warning
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Warning -> Warning -> Bool
== :: Warning -> Warning -> Bool
$c/= :: Warning -> Warning -> Bool
/= :: Warning -> Warning -> Bool
Eq, Int -> Warning -> ShowS
[Warning] -> ShowS
Warning -> String
(Int -> Warning -> ShowS)
-> (Warning -> String) -> ([Warning] -> ShowS) -> Show Warning
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Warning -> ShowS
showsPrec :: Int -> Warning -> ShowS
$cshow :: Warning -> String
show :: Warning -> String
$cshowList :: [Warning] -> ShowS
showList :: [Warning] -> ShowS
Show, (forall x. Warning -> Rep Warning x)
-> (forall x. Rep Warning x -> Warning) -> Generic Warning
forall x. Rep Warning x -> Warning
forall x. Warning -> Rep Warning x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Warning -> Rep Warning x
from :: forall x. Warning -> Rep Warning x
$cto :: forall x. Rep Warning x -> Warning
to :: forall x. Rep Warning x -> Warning
Generic)

instance NFData Warning

-- | The ping message (type 18).
data Ping = Ping
  { Ping -> Word16
pingNumPongBytes :: {-# UNPACK #-} !Word16
  , Ping -> ByteString
pingIgnored      :: !BS.ByteString
  } deriving stock (Ping -> Ping -> Bool
(Ping -> Ping -> Bool) -> (Ping -> Ping -> Bool) -> Eq Ping
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Ping -> Ping -> Bool
== :: Ping -> Ping -> Bool
$c/= :: Ping -> Ping -> Bool
/= :: Ping -> Ping -> Bool
Eq, Int -> Ping -> ShowS
[Ping] -> ShowS
Ping -> String
(Int -> Ping -> ShowS)
-> (Ping -> String) -> ([Ping] -> ShowS) -> Show Ping
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Ping -> ShowS
showsPrec :: Int -> Ping -> ShowS
$cshow :: Ping -> String
show :: Ping -> String
$cshowList :: [Ping] -> ShowS
showList :: [Ping] -> ShowS
Show, (forall x. Ping -> Rep Ping x)
-> (forall x. Rep Ping x -> Ping) -> Generic Ping
forall x. Rep Ping x -> Ping
forall x. Ping -> Rep Ping x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Ping -> Rep Ping x
from :: forall x. Ping -> Rep Ping x
$cto :: forall x. Rep Ping x -> Ping
to :: forall x. Rep Ping x -> Ping
Generic)

instance NFData Ping

-- | The pong message (type 19).
data Pong = Pong
  { Pong -> ByteString
pongIgnored :: !BS.ByteString
  } deriving stock (Pong -> Pong -> Bool
(Pong -> Pong -> Bool) -> (Pong -> Pong -> Bool) -> Eq Pong
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Pong -> Pong -> Bool
== :: Pong -> Pong -> Bool
$c/= :: Pong -> Pong -> Bool
/= :: Pong -> Pong -> Bool
Eq, Int -> Pong -> ShowS
[Pong] -> ShowS
Pong -> String
(Int -> Pong -> ShowS)
-> (Pong -> String) -> ([Pong] -> ShowS) -> Show Pong
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Pong -> ShowS
showsPrec :: Int -> Pong -> ShowS
$cshow :: Pong -> String
show :: Pong -> String
$cshowList :: [Pong] -> ShowS
showList :: [Pong] -> ShowS
Show, (forall x. Pong -> Rep Pong x)
-> (forall x. Rep Pong x -> Pong) -> Generic Pong
forall x. Rep Pong x -> Pong
forall x. Pong -> Rep Pong x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Pong -> Rep Pong x
from :: forall x. Pong -> Rep Pong x
$cto :: forall x. Rep Pong x -> Pong
to :: forall x. Rep Pong x -> Pong
Generic)

instance NFData Pong

-- | The peer_storage message (type 7).
data PeerStorage = PeerStorage
  { PeerStorage -> ByteString
peerStorageBlob :: !BS.ByteString
  } deriving stock (PeerStorage -> PeerStorage -> Bool
(PeerStorage -> PeerStorage -> Bool)
-> (PeerStorage -> PeerStorage -> Bool) -> Eq PeerStorage
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PeerStorage -> PeerStorage -> Bool
== :: PeerStorage -> PeerStorage -> Bool
$c/= :: PeerStorage -> PeerStorage -> Bool
/= :: PeerStorage -> PeerStorage -> Bool
Eq, Int -> PeerStorage -> ShowS
[PeerStorage] -> ShowS
PeerStorage -> String
(Int -> PeerStorage -> ShowS)
-> (PeerStorage -> String)
-> ([PeerStorage] -> ShowS)
-> Show PeerStorage
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PeerStorage -> ShowS
showsPrec :: Int -> PeerStorage -> ShowS
$cshow :: PeerStorage -> String
show :: PeerStorage -> String
$cshowList :: [PeerStorage] -> ShowS
showList :: [PeerStorage] -> ShowS
Show, (forall x. PeerStorage -> Rep PeerStorage x)
-> (forall x. Rep PeerStorage x -> PeerStorage)
-> Generic PeerStorage
forall x. Rep PeerStorage x -> PeerStorage
forall x. PeerStorage -> Rep PeerStorage x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. PeerStorage -> Rep PeerStorage x
from :: forall x. PeerStorage -> Rep PeerStorage x
$cto :: forall x. Rep PeerStorage x -> PeerStorage
to :: forall x. Rep PeerStorage x -> PeerStorage
Generic)

instance NFData PeerStorage

-- | The peer_storage_retrieval message (type 9).
data PeerStorageRetrieval = PeerStorageRetrieval
  { PeerStorageRetrieval -> ByteString
peerStorageRetrievalBlob :: !BS.ByteString
  } deriving stock (PeerStorageRetrieval -> PeerStorageRetrieval -> Bool
(PeerStorageRetrieval -> PeerStorageRetrieval -> Bool)
-> (PeerStorageRetrieval -> PeerStorageRetrieval -> Bool)
-> Eq PeerStorageRetrieval
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PeerStorageRetrieval -> PeerStorageRetrieval -> Bool
== :: PeerStorageRetrieval -> PeerStorageRetrieval -> Bool
$c/= :: PeerStorageRetrieval -> PeerStorageRetrieval -> Bool
/= :: PeerStorageRetrieval -> PeerStorageRetrieval -> Bool
Eq, Int -> PeerStorageRetrieval -> ShowS
[PeerStorageRetrieval] -> ShowS
PeerStorageRetrieval -> String
(Int -> PeerStorageRetrieval -> ShowS)
-> (PeerStorageRetrieval -> String)
-> ([PeerStorageRetrieval] -> ShowS)
-> Show PeerStorageRetrieval
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PeerStorageRetrieval -> ShowS
showsPrec :: Int -> PeerStorageRetrieval -> ShowS
$cshow :: PeerStorageRetrieval -> String
show :: PeerStorageRetrieval -> String
$cshowList :: [PeerStorageRetrieval] -> ShowS
showList :: [PeerStorageRetrieval] -> ShowS
Show, (forall x. PeerStorageRetrieval -> Rep PeerStorageRetrieval x)
-> (forall x. Rep PeerStorageRetrieval x -> PeerStorageRetrieval)
-> Generic PeerStorageRetrieval
forall x. Rep PeerStorageRetrieval x -> PeerStorageRetrieval
forall x. PeerStorageRetrieval -> Rep PeerStorageRetrieval x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. PeerStorageRetrieval -> Rep PeerStorageRetrieval x
from :: forall x. PeerStorageRetrieval -> Rep PeerStorageRetrieval x
$cto :: forall x. Rep PeerStorageRetrieval x -> PeerStorageRetrieval
to :: forall x. Rep PeerStorageRetrieval x -> PeerStorageRetrieval
Generic)

instance NFData PeerStorageRetrieval

-- | All BOLT #1 messages.
data Message
  = MsgInitVal !Init
  | MsgErrorVal !Error
  | MsgWarningVal !Warning
  | MsgPingVal !Ping
  | MsgPongVal !Pong
  | MsgPeerStorageVal !PeerStorage
  | MsgPeerStorageRetrievalVal !PeerStorageRetrieval
  deriving stock (Message -> Message -> Bool
(Message -> Message -> Bool)
-> (Message -> Message -> Bool) -> Eq Message
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Message -> Message -> Bool
== :: Message -> Message -> Bool
$c/= :: Message -> Message -> Bool
/= :: Message -> Message -> Bool
Eq, Int -> Message -> ShowS
[Message] -> ShowS
Message -> String
(Int -> Message -> ShowS)
-> (Message -> String) -> ([Message] -> ShowS) -> Show Message
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Message -> ShowS
showsPrec :: Int -> Message -> ShowS
$cshow :: Message -> String
show :: Message -> String
$cshowList :: [Message] -> ShowS
showList :: [Message] -> ShowS
Show, (forall x. Message -> Rep Message x)
-> (forall x. Rep Message x -> Message) -> Generic Message
forall x. Rep Message x -> Message
forall x. Message -> Rep Message x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Message -> Rep Message x
from :: forall x. Message -> Rep Message x
$cto :: forall x. Rep Message x -> Message
to :: forall x. Rep Message x -> Message
Generic)

instance NFData Message

-- | Get the message type for a message.
messageType :: Message -> MsgType
messageType :: Message -> MsgType
messageType (MsgInitVal Init
_)                 = MsgType
MsgInit
messageType (MsgErrorVal Error
_)                = MsgType
MsgError
messageType (MsgWarningVal Warning
_)              = MsgType
MsgWarning
messageType (MsgPingVal Ping
_)                 = MsgType
MsgPing
messageType (MsgPongVal Pong
_)                 = MsgType
MsgPong
messageType (MsgPeerStorageVal PeerStorage
_)          = MsgType
MsgPeerStorage
messageType (MsgPeerStorageRetrievalVal PeerStorageRetrieval
_) = MsgType
MsgPeerStorageRet

-- Message envelope ------------------------------------------------------------

-- | A complete message envelope with type, payload, and optional extension.
data Envelope = Envelope
  { Envelope -> MsgType
envType      :: !MsgType
  , Envelope -> ByteString
envPayload   :: !BS.ByteString
  , Envelope -> Maybe TlvStream
envExtension :: !(Maybe TlvStream)
  } deriving stock (Envelope -> Envelope -> Bool
(Envelope -> Envelope -> Bool)
-> (Envelope -> Envelope -> Bool) -> Eq Envelope
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Envelope -> Envelope -> Bool
== :: Envelope -> Envelope -> Bool
$c/= :: Envelope -> Envelope -> Bool
/= :: Envelope -> Envelope -> Bool
Eq, Int -> Envelope -> ShowS
[Envelope] -> ShowS
Envelope -> String
(Int -> Envelope -> ShowS)
-> (Envelope -> String) -> ([Envelope] -> ShowS) -> Show Envelope
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Envelope -> ShowS
showsPrec :: Int -> Envelope -> ShowS
$cshow :: Envelope -> String
show :: Envelope -> String
$cshowList :: [Envelope] -> ShowS
showList :: [Envelope] -> ShowS
Show, (forall x. Envelope -> Rep Envelope x)
-> (forall x. Rep Envelope x -> Envelope) -> Generic Envelope
forall x. Rep Envelope x -> Envelope
forall x. Envelope -> Rep Envelope x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Envelope -> Rep Envelope x
from :: forall x. Envelope -> Rep Envelope x
$cto :: forall x. Rep Envelope x -> Envelope
to :: forall x. Rep Envelope x -> Envelope
Generic)

instance NFData Envelope