hwormhole-0.1.0.0: src/Transit/Internal/Messages.hs
-- | Description: Client-to-Client messages
-- The JSON messages are derived from these Message types.
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Transit.Internal.Messages
( TransitMsg(..)
, Ability(..)
, AbilityV1(..)
, Hint(..)
, ConnectionHint(..)
, Ack(..)
, TransitAck(..)
) where
import Protolude
import Data.Aeson
( FromJSON(..)
, ToJSON(..)
, genericToJSON
, genericParseJSON
, defaultOptions
, fieldLabelModifier
, constructorTagModifier
, sumEncoding
, SumEncoding(..)
, camelTo2
)
import qualified Data.Set as Set
-- | Type to represent the abilities
data AbilityV1
= DirectTcpV1
-- ^ Can send directly via TCP
| RelayV1
-- ^ Can relay via a relay server
deriving (Eq, Show, Generic)
instance ToJSON AbilityV1 where
toJSON = genericToJSON
defaultOptions { constructorTagModifier = camelTo2 '-'}
instance FromJSON AbilityV1 where
parseJSON = genericParseJSON
defaultOptions { constructorTagModifier = camelTo2 '-'}
-- | Hints are messages that specify ways that the client
-- can connect to the peer.
data Hint = Hint { ctype :: AbilityV1
, priority :: Double
, hostname :: Text
, port :: Word16 }
deriving (Eq, Show, Generic)
instance Ord Hint where
Hint _ p1 _ _ `compare` Hint _ p2 _ _ = Down p1 `compare` Down p2
instance ToJSON Hint where
toJSON = genericToJSON
defaultOptions { fieldLabelModifier =
\name -> case name of
"ctype" -> "type"
_ -> name }
instance FromJSON Hint where
parseJSON = genericParseJSON
defaultOptions { fieldLabelModifier =
\name -> case name of
"ctype" -> "type"
_ -> name }
-- | Connection Hint is currently a direct hint or a relay hint
data ConnectionHint
= Direct Hint
-- ^ Direct Hint
| Relay { rtype :: AbilityV1
, hints :: [Hint] }
-- ^ Relay hint
deriving (Eq, Show, Generic)
instance Ord ConnectionHint where
Direct _ `compare` Direct _ = EQ
Direct _ `compare` Relay _ _ = LT
Relay _ h1 `compare` Relay _ h2 = h1 `compare` h2
Relay _ _ `compare` Direct _ = GT
instance ToJSON ConnectionHint where
toJSON = genericToJSON
defaultOptions { sumEncoding = UntaggedValue
, fieldLabelModifier =
\name -> case name of
"rtype" -> "type"
_ -> name }
instance FromJSON ConnectionHint where
parseJSON = genericParseJSON
defaultOptions { sumEncoding = UntaggedValue
, fieldLabelModifier =
\name -> case name of
"rtype" -> "type"
_ -> name }
-- | Ack message type
data Ack = FileAck Text
-- ^ File Ack
| MessageAck Text
-- ^ Message Ack
deriving (Eq, Show, Generic)
instance ToJSON Ack where
toJSON = genericToJSON
defaultOptions { sumEncoding = ObjectWithSingleField
, constructorTagModifier = camelTo2 '_'}
instance FromJSON Ack where
parseJSON = genericParseJSON
defaultOptions { sumEncoding = ObjectWithSingleField
, constructorTagModifier = camelTo2 '_'}
-- | A newtype specifically for generating Ability JSON messages
newtype Ability = Ability { atype :: AbilityV1 }
deriving (Eq, Show, Generic)
instance ToJSON Ability where
toJSON = genericToJSON
defaultOptions { sumEncoding = UntaggedValue
, fieldLabelModifier = const "type" }
instance FromJSON Ability where
parseJSON = genericParseJSON
defaultOptions { sumEncoding = UntaggedValue
, fieldLabelModifier = const "type" }
-- | Transit, Answer and Error Message from Client to Client
data TransitMsg = Error Text
| Answer Ack
-- ^ Answer message is sent on a successful transfer
| Transit { abilitiesV1 :: [Ability]
, hintsV1 :: Set.Set ConnectionHint }
-- ^ Transit message
deriving (Eq, Show, Generic)
instance ToJSON TransitMsg where
toJSON = genericToJSON
defaultOptions { sumEncoding = ObjectWithSingleField
, constructorTagModifier = camelTo2 '-'
, fieldLabelModifier = camelTo2 '-' }
instance FromJSON TransitMsg where
parseJSON = genericParseJSON
defaultOptions { sumEncoding = ObjectWithSingleField
, constructorTagModifier = camelTo2 '-'
, fieldLabelModifier = camelTo2 '-'}
-- | Message sent by the receiver of the file to the sender
data TransitAck
= TransitAck
{ ack :: Text -- ^ "ack" is "ok" implies a successful transfer
, sha256 :: Text } -- ^ expected sha256 sum of the transfered file
deriving (Eq, Show, Generic)
instance ToJSON TransitAck where
toJSON = genericToJSON
defaultOptions { sumEncoding = UntaggedValue }
instance FromJSON TransitAck where
parseJSON = genericParseJSON
defaultOptions { sumEncoding = UntaggedValue }