-----------------------------------------------------------------------------
-- |
-- Module      :  BfHaskell.StreamingAPI.Model
-- Copyright   :  (C) 2020 Martins Erts
-- License     :  MIT
-- Maintainer  :  Martins Erts <martins.erts@gmail.com>
-- Stability   :  experimental

{-
   Betfair: Exchange Streaming API

   API to receive streamed updates. This is an ssl socket connection of CRLF delimited json messages (see RequestMessage & ResponseMessage)

   OpenAPI spec version: 2.0
   Betfair: Exchange Streaming API API version: 1.0.1423
   Contact: bdp@betfair.com
   Generated by Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
-}

{-# LANGUAGE DeriveDataTypeable         #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase                 #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE RecordWildCards            #-}
{-# LANGUAGE TypeFamilies               #-}
{-# OPTIONS_GHC -fno-warn-unused-matches -fno-warn-unused-binds -fno-warn-unused-imports #-}

module BfHaskell.StreamingAPI.Model where

import           Data.Aeson           ((.:), (.:!), (.:?), (.=))

import qualified Control.Arrow        as P (left)
import qualified Data.Aeson           as A
import qualified Data.ByteString      as B
import qualified Data.ByteString.Lazy as BL
import qualified Data.Data            as P (Data, Typeable)
import qualified Data.Foldable        as P
import qualified Data.HashMap.Lazy    as HM
import qualified Data.Map             as Map
import qualified Data.Maybe           as P
import qualified Data.Set             as Set
import qualified Data.Text            as T
import qualified Data.Text.Encoding   as T
import qualified Data.Time            as TI
import qualified Data.Time.ISO8601    as TI

import           Control.Applicative  (Alternative)
import           Data.Text            (Text)
import           Prelude              (Applicative, Bool (..), Char, Double,
                                       FilePath, Float, Functor, Int, Integer,
                                       Maybe (..), Monad, String, fmap, maybe,
                                       mempty, pure, undefined, ($), (.), (<$>),
                                       (<*>), (=<<), (>>=))

import qualified Prelude              as P



-- * Models
-- * DateTime Formatting


newtype DateTime = DateTime { unDateTime :: TI.UTCTime }
  deriving (P.Eq,P.Data,P.Ord,P.Typeable,TI.ParseTime,TI.FormatTime)
instance A.FromJSON DateTime where
  parseJSON = A.withText "DateTime" (_readDateTime . T.unpack)
instance A.ToJSON DateTime where
  toJSON (DateTime t) = A.toJSON (_showDateTime t)
instance P.Show DateTime where
  show (DateTime t) = _showDateTime t

-- | @_parseISO8601@
_readDateTime :: (TI.ParseTime t, Monad m, Alternative m) => String -> m t
_readDateTime =
  _parseISO8601
{-# INLINE _readDateTime #-}

-- | @TI.formatISO8601Millis@
_showDateTime :: (t ~ TI.UTCTime, TI.FormatTime t) => t -> String
_showDateTime =
  TI.formatISO8601Millis
{-# INLINE _showDateTime #-}

-- | parse an ISO8601 date-time string
_parseISO8601 :: (TI.ParseTime t, Monad m, Alternative m) => String -> m t
_parseISO8601 t =
  P.asum $
  P.flip (TI.parseTimeM True TI.defaultTimeLocale) t <$>
  ["%FT%T%QZ", "%FT%T%Q%z", "%FT%T%Q%Z"]
{-# INLINE _parseISO8601 #-}

_omitNulls :: [(Text, A.Value)] -> A.Value
_omitNulls = A.object . P.filter notNull
  where
    notNull (_, A.Null) = False
    notNull _           = True




-- ** AllRequestTypesExample
-- | AllRequestTypesExample
data AllRequestTypesExample = AllRequestTypesExample
  { allRequestTypesExampleOpTypes :: !(Maybe E'OpTypes) -- ^ "opTypes"
  , allRequestTypesExampleHeartbeat :: !(Maybe HeartbeatMessage) -- ^ "heartbeat"
  , allRequestTypesExampleOrderSubscriptionMessage :: !(Maybe OrderSubscriptionMessage) -- ^ "orderSubscriptionMessage"
  , allRequestTypesExampleMarketSubscription :: !(Maybe MarketSubscriptionMessage) -- ^ "marketSubscription"
  , allRequestTypesExampleAuthentication :: !(Maybe AuthenticationMessage) -- ^ "authentication"
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON AllRequestTypesExample
instance A.FromJSON AllRequestTypesExample where
  parseJSON = A.withObject "AllRequestTypesExample" $ \o ->
    AllRequestTypesExample
      <$> (o .:? "opTypes")
      <*> (o .:? "heartbeat")
      <*> (o .:? "orderSubscriptionMessage")
      <*> (o .:? "marketSubscription")
      <*> (o .:? "authentication")

-- | ToJSON AllRequestTypesExample
instance A.ToJSON AllRequestTypesExample where
  toJSON AllRequestTypesExample {..} =
   _omitNulls
      [ "opTypes" .= allRequestTypesExampleOpTypes
      , "heartbeat" .= allRequestTypesExampleHeartbeat
      , "orderSubscriptionMessage" .= allRequestTypesExampleOrderSubscriptionMessage
      , "marketSubscription" .= allRequestTypesExampleMarketSubscription
      , "authentication" .= allRequestTypesExampleAuthentication
      ]


-- | Construct a value of type 'AllRequestTypesExample' (by applying it's required fields, if any)
mkAllRequestTypesExample
  :: AllRequestTypesExample
mkAllRequestTypesExample =
  AllRequestTypesExample
  { allRequestTypesExampleOpTypes = Nothing
  , allRequestTypesExampleHeartbeat = Nothing
  , allRequestTypesExampleOrderSubscriptionMessage = Nothing
  , allRequestTypesExampleMarketSubscription = Nothing
  , allRequestTypesExampleAuthentication = Nothing
  }

-- | StreamResponse
data StreamResponse = SRMarketChangeMessage MarketChangeMessage
                      | SRConnectionMessage ConnectionMessage
                      | SROrderChangeMessage OrderChangeMessage
                      | SRStatusMessage StatusMessage
                      deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON StreamResponse
instance A.FromJSON StreamResponse where
  parseJSON = A.withObject "StreamResponse" $ \o -> do
    opType <- o .: "op"
    let v = A.Object o
    case opType of
      E'OpTypes2'Connection -> SRConnectionMessage <$> A.parseJSON v
      E'OpTypes2'Status     -> SRStatusMessage <$> A.parseJSON v
      E'OpTypes2'Mcm        -> SRMarketChangeMessage <$> A.parseJSON v
      E'OpTypes2'Ocm        -> SROrderChangeMessage <$> A.parseJSON v


-- ** AllResponseTypesExample
-- | AllResponseTypesExample
data AllResponseTypesExample = AllResponseTypesExample
  { allResponseTypesExampleOpTypes             :: !(Maybe E'OpTypes2) -- ^ "opTypes"
  , allResponseTypesExampleMarketChangeMessage :: !(Maybe MarketChangeMessage) -- ^ "marketChangeMessage"
  , allResponseTypesExampleConnection          :: !(Maybe ConnectionMessage) -- ^ "connection"
  , allResponseTypesExampleOrderChangeMessage  :: !(Maybe OrderChangeMessage) -- ^ "orderChangeMessage"
  , allResponseTypesExampleStatus              :: !(Maybe StatusMessage) -- ^ "status"
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON AllResponseTypesExample
instance A.FromJSON AllResponseTypesExample where
  parseJSON = A.withObject "AllResponseTypesExample" $ \o ->
    AllResponseTypesExample
      <$> (o .:? "opTypes")
      <*> (o .:? "marketChangeMessage")
      <*> (o .:? "connection")
      <*> (o .:? "orderChangeMessage")
      <*> (o .:? "status")

-- | ToJSON AllResponseTypesExample
instance A.ToJSON AllResponseTypesExample where
  toJSON AllResponseTypesExample {..} =
   _omitNulls
      [ "opTypes" .= allResponseTypesExampleOpTypes
      , "marketChangeMessage" .= allResponseTypesExampleMarketChangeMessage
      , "connection" .= allResponseTypesExampleConnection
      , "orderChangeMessage" .= allResponseTypesExampleOrderChangeMessage
      , "status" .= allResponseTypesExampleStatus
      ]


-- | Construct a value of type 'AllResponseTypesExample' (by applying it's required fields, if any)
mkAllResponseTypesExample
  :: AllResponseTypesExample
mkAllResponseTypesExample =
  AllResponseTypesExample
  { allResponseTypesExampleOpTypes = Nothing
  , allResponseTypesExampleMarketChangeMessage = Nothing
  , allResponseTypesExampleConnection = Nothing
  , allResponseTypesExampleOrderChangeMessage = Nothing
  , allResponseTypesExampleStatus = Nothing
  }

-- ** KeyLineDefinition
-- | KeyLineDefinition
data KeyLineDefinition = KeyLineDefinition
  { keyLineDefinitionKl :: !(Maybe [KeyLineSelection]) -- ^ "kl"
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON KeyLineDefinition
instance A.FromJSON KeyLineDefinition where
  parseJSON = A.withObject "KeyLineDefinition" $ \o ->
    KeyLineDefinition
      <$> (o .:? "kl")

-- | ToJSON KeyLineDefinition
instance A.ToJSON KeyLineDefinition where
  toJSON KeyLineDefinition {..} =
   _omitNulls
      [ "kl" .= keyLineDefinitionKl
      ]


-- | Construct a value of type 'KeyLineDefinition' (by applying it's required fields, if any)
mkKeyLineDefinition
  :: KeyLineDefinition
mkKeyLineDefinition =
  KeyLineDefinition
  { keyLineDefinitionKl = Nothing
  }

-- ** KeyLineSelection
-- | KeyLineSelection
data KeyLineSelection = KeyLineSelection
  { keyLineSelectionId :: !(Maybe Integer) -- ^ "id"
  , keyLineSelectionHc :: !(Maybe Double) -- ^ "hc"
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON KeyLineSelection
instance A.FromJSON KeyLineSelection where
  parseJSON = A.withObject "KeyLineSelection" $ \o ->
    KeyLineSelection
      <$> (o .:? "id")
      <*> (o .:? "hc")

-- | ToJSON KeyLineSelection
instance A.ToJSON KeyLineSelection where
  toJSON KeyLineSelection {..} =
   _omitNulls
      [ "id" .= keyLineSelectionId
      , "hc" .= keyLineSelectionHc
      ]


-- | Construct a value of type 'KeyLineSelection' (by applying it's required fields, if any)
mkKeyLineSelection
  :: KeyLineSelection
mkKeyLineSelection =
  KeyLineSelection
  { keyLineSelectionId = Nothing
  , keyLineSelectionHc = Nothing
  }

-- ** MarketChange
-- | MarketChange
data MarketChange = MarketChange
  { marketChangeRc               :: !(Maybe [RunnerChange]) -- ^ "rc" - Runner Changes - a list of changes to runners (or null if un-changed)
  , marketChangeImg              :: !(Maybe Bool) -- ^ "img" - Image - replace existing prices / data with the data supplied: it is not a delta (or null if delta)
  , marketChangeTv               :: !(Maybe Double) -- ^ "tv" - The total amount matched across the market. This value is truncated at 2dp (or null if un-changed)
  , marketChangeCon              :: !(Maybe Bool) -- ^ "con" - Conflated - have more than a single change been combined (or null if not conflated)
  , marketChangeMarketDefinition :: !(Maybe MarketDefinition) -- ^ "marketDefinition" - Market Definition - the definition of the market (or null if un-changed)
  , marketChangeId               :: !(Maybe Text) -- ^ "id" - Market Id - the id of the market
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON MarketChange
instance A.FromJSON MarketChange where
  parseJSON = A.withObject "MarketChange" $ \o ->
    MarketChange
      <$> (o .:? "rc")
      <*> (o .:? "img")
      <*> (o .:? "tv")
      <*> (o .:? "con")
      <*> (o .:? "marketDefinition")
      <*> (o .:? "id")

-- | ToJSON MarketChange
instance A.ToJSON MarketChange where
  toJSON MarketChange {..} =
   _omitNulls
      [ "rc" .= marketChangeRc
      , "img" .= marketChangeImg
      , "tv" .= marketChangeTv
      , "con" .= marketChangeCon
      , "marketDefinition" .= marketChangeMarketDefinition
      , "id" .= marketChangeId
      ]


-- | Construct a value of type 'MarketChange' (by applying it's required fields, if any)
mkMarketChange
  :: MarketChange
mkMarketChange =
  MarketChange
  { marketChangeRc = Nothing
  , marketChangeImg = Nothing
  , marketChangeTv = Nothing
  , marketChangeCon = Nothing
  , marketChangeMarketDefinition = Nothing
  , marketChangeId = Nothing
  }

-- ** MarketDataFilter
-- | MarketDataFilter
data MarketDataFilter = MarketDataFilter
  { marketDataFilterLadderLevels :: !(Maybe Int) -- ^ "ladderLevels"
  , marketDataFilterFields       :: !(Maybe [E'Fields]) -- ^ "fields"
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON MarketDataFilter
instance A.FromJSON MarketDataFilter where
  parseJSON = A.withObject "MarketDataFilter" $ \o ->
    MarketDataFilter
      <$> (o .:? "ladderLevels")
      <*> (o .:? "fields")

-- | ToJSON MarketDataFilter
instance A.ToJSON MarketDataFilter where
  toJSON MarketDataFilter {..} =
   _omitNulls
      [ "ladderLevels" .= marketDataFilterLadderLevels
      , "fields" .= marketDataFilterFields
      ]


-- | Construct a value of type 'MarketDataFilter' (by applying it's required fields, if any)
mkMarketDataFilter
  :: MarketDataFilter
mkMarketDataFilter =
  MarketDataFilter
  { marketDataFilterLadderLevels = Nothing
  , marketDataFilterFields = Nothing
  }

-- ** MarketDefinition
-- | MarketDefinition
data MarketDefinition = MarketDefinition
  { marketDefinitionVenue                 :: !(Maybe Text) -- ^ "venue"
  , marketDefinitionRaceType              :: !(Maybe Text) -- ^ "raceType"
  , marketDefinitionSettledTime           :: !(Maybe DateTime) -- ^ "settledTime"
  , marketDefinitionTimezone              :: !(Maybe Text) -- ^ "timezone"
  , marketDefinitionEachWayDivisor        :: !(Maybe Double) -- ^ "eachWayDivisor"
  , marketDefinitionRegulators            :: !(Maybe [Text]) -- ^ "regulators" - The market regulators.
  , marketDefinitionMarketType            :: !(Maybe Text) -- ^ "marketType"
  , marketDefinitionMarketBaseRate        :: !(Maybe Double) -- ^ "marketBaseRate"
  , marketDefinitionNumberOfWinners       :: !(Maybe Int) -- ^ "numberOfWinners"
  , marketDefinitionCountryCode           :: !(Maybe Text) -- ^ "countryCode"
  , marketDefinitionLineMaxUnit           :: !(Maybe Double) -- ^ "lineMaxUnit" - For Handicap and Line markets, the maximum value for the outcome, in market units for this market (eg 100 runs).
  , marketDefinitionInPlay                :: !(Maybe Bool) -- ^ "inPlay"
  , marketDefinitionBetDelay              :: !(Maybe Int) -- ^ "betDelay"
  , marketDefinitionBspMarket             :: !(Maybe Bool) -- ^ "bspMarket"
  , marketDefinitionBettingType           :: !(Maybe E'BettingTypes) -- ^ "bettingType"
  , marketDefinitionNumberOfActiveRunners :: !(Maybe Int) -- ^ "numberOfActiveRunners"
  , marketDefinitionLineMinUnit           :: !(Maybe Double) -- ^ "lineMinUnit" - For Handicap and Line markets, the minimum value for the outcome, in market units for this market (eg 0 runs).
  , marketDefinitionEventId               :: !(Maybe Text) -- ^ "eventId"
  , marketDefinitionCrossMatching         :: !(Maybe Bool) -- ^ "crossMatching"
  , marketDefinitionRunnersVoidable       :: !(Maybe Bool) -- ^ "runnersVoidable"
  , marketDefinitionTurnInPlayEnabled     :: !(Maybe Bool) -- ^ "turnInPlayEnabled"
  , marketDefinitionPriceLadderDefinition :: !(Maybe PriceLadderDefinition) -- ^ "priceLadderDefinition" - Definition of the price ladder type and any related data.
  , marketDefinitionKeyLineDefinition     :: !(Maybe KeyLineDefinition) -- ^ "keyLineDefinition" - Definition of a markets key line selection (for valid markets), comprising the selectionId and handicap of the team it is applied to.
  , marketDefinitionSuspendTime           :: !(Maybe DateTime) -- ^ "suspendTime"
  , marketDefinitionDiscountAllowed       :: !(Maybe Bool) -- ^ "discountAllowed"
  , marketDefinitionPersistenceEnabled    :: !(Maybe Bool) -- ^ "persistenceEnabled"
  , marketDefinitionRunners               :: !(Maybe [RunnerDefinition]) -- ^ "runners"
  , marketDefinitionVersion               :: !(Maybe Integer) -- ^ "version"
  , marketDefinitionEventTypeId           :: !(Maybe Text) -- ^ "eventTypeId" - The Event Type the market is contained within.
  , marketDefinitionComplete              :: !(Maybe Bool) -- ^ "complete"
  , marketDefinitionOpenDate              :: !(Maybe DateTime) -- ^ "openDate"
  , marketDefinitionMarketTime            :: !(Maybe DateTime) -- ^ "marketTime"
  , marketDefinitionBspReconciled         :: !(Maybe Bool) -- ^ "bspReconciled"
  , marketDefinitionLineInterval          :: !(Maybe Double) -- ^ "lineInterval" - For Handicap and Line markets, the lines available on this market will be between the range of lineMinUnit and lineMaxUnit, in increments of the lineInterval value. e.g. If unit is runs, lineMinUnit&#x3D;10, lineMaxUnit&#x3D;20 and lineInterval&#x3D;0.5, then valid lines include 10, 10.5, 11, 11.5 up to 20 runs.
  , marketDefinitionStatus                :: !(Maybe E'Status) -- ^ "status"
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON MarketDefinition
instance A.FromJSON MarketDefinition where
  parseJSON = A.withObject "MarketDefinition" $ \o ->
    MarketDefinition
      <$> (o .:? "venue")
      <*> (o .:? "raceType")
      <*> (o .:? "settledTime")
      <*> (o .:? "timezone")
      <*> (o .:? "eachWayDivisor")
      <*> (o .:? "regulators")
      <*> (o .:? "marketType")
      <*> (o .:? "marketBaseRate")
      <*> (o .:? "numberOfWinners")
      <*> (o .:? "countryCode")
      <*> (o .:? "lineMaxUnit")
      <*> (o .:? "inPlay")
      <*> (o .:? "betDelay")
      <*> (o .:? "bspMarket")
      <*> (o .:? "bettingType")
      <*> (o .:? "numberOfActiveRunners")
      <*> (o .:? "lineMinUnit")
      <*> (o .:? "eventId")
      <*> (o .:? "crossMatching")
      <*> (o .:? "runnersVoidable")
      <*> (o .:? "turnInPlayEnabled")
      <*> (o .:? "priceLadderDefinition")
      <*> (o .:? "keyLineDefinition")
      <*> (o .:? "suspendTime")
      <*> (o .:? "discountAllowed")
      <*> (o .:? "persistenceEnabled")
      <*> (o .:? "runners")
      <*> (o .:? "version")
      <*> (o .:? "eventTypeId")
      <*> (o .:? "complete")
      <*> (o .:? "openDate")
      <*> (o .:? "marketTime")
      <*> (o .:? "bspReconciled")
      <*> (o .:? "lineInterval")
      <*> (o .:? "status")

-- | ToJSON MarketDefinition
instance A.ToJSON MarketDefinition where
  toJSON MarketDefinition {..} =
   _omitNulls
      [ "venue" .= marketDefinitionVenue
      , "raceType" .= marketDefinitionRaceType
      , "settledTime" .= marketDefinitionSettledTime
      , "timezone" .= marketDefinitionTimezone
      , "eachWayDivisor" .= marketDefinitionEachWayDivisor
      , "regulators" .= marketDefinitionRegulators
      , "marketType" .= marketDefinitionMarketType
      , "marketBaseRate" .= marketDefinitionMarketBaseRate
      , "numberOfWinners" .= marketDefinitionNumberOfWinners
      , "countryCode" .= marketDefinitionCountryCode
      , "lineMaxUnit" .= marketDefinitionLineMaxUnit
      , "inPlay" .= marketDefinitionInPlay
      , "betDelay" .= marketDefinitionBetDelay
      , "bspMarket" .= marketDefinitionBspMarket
      , "bettingType" .= marketDefinitionBettingType
      , "numberOfActiveRunners" .= marketDefinitionNumberOfActiveRunners
      , "lineMinUnit" .= marketDefinitionLineMinUnit
      , "eventId" .= marketDefinitionEventId
      , "crossMatching" .= marketDefinitionCrossMatching
      , "runnersVoidable" .= marketDefinitionRunnersVoidable
      , "turnInPlayEnabled" .= marketDefinitionTurnInPlayEnabled
      , "priceLadderDefinition" .= marketDefinitionPriceLadderDefinition
      , "keyLineDefinition" .= marketDefinitionKeyLineDefinition
      , "suspendTime" .= marketDefinitionSuspendTime
      , "discountAllowed" .= marketDefinitionDiscountAllowed
      , "persistenceEnabled" .= marketDefinitionPersistenceEnabled
      , "runners" .= marketDefinitionRunners
      , "version" .= marketDefinitionVersion
      , "eventTypeId" .= marketDefinitionEventTypeId
      , "complete" .= marketDefinitionComplete
      , "openDate" .= marketDefinitionOpenDate
      , "marketTime" .= marketDefinitionMarketTime
      , "bspReconciled" .= marketDefinitionBspReconciled
      , "lineInterval" .= marketDefinitionLineInterval
      , "status" .= marketDefinitionStatus
      ]


-- | Construct a value of type 'MarketDefinition' (by applying it's required fields, if any)
mkMarketDefinition
  :: MarketDefinition
mkMarketDefinition =
  MarketDefinition
  { marketDefinitionVenue = Nothing
  , marketDefinitionRaceType = Nothing
  , marketDefinitionSettledTime = Nothing
  , marketDefinitionTimezone = Nothing
  , marketDefinitionEachWayDivisor = Nothing
  , marketDefinitionRegulators = Nothing
  , marketDefinitionMarketType = Nothing
  , marketDefinitionMarketBaseRate = Nothing
  , marketDefinitionNumberOfWinners = Nothing
  , marketDefinitionCountryCode = Nothing
  , marketDefinitionLineMaxUnit = Nothing
  , marketDefinitionInPlay = Nothing
  , marketDefinitionBetDelay = Nothing
  , marketDefinitionBspMarket = Nothing
  , marketDefinitionBettingType = Nothing
  , marketDefinitionNumberOfActiveRunners = Nothing
  , marketDefinitionLineMinUnit = Nothing
  , marketDefinitionEventId = Nothing
  , marketDefinitionCrossMatching = Nothing
  , marketDefinitionRunnersVoidable = Nothing
  , marketDefinitionTurnInPlayEnabled = Nothing
  , marketDefinitionPriceLadderDefinition = Nothing
  , marketDefinitionKeyLineDefinition = Nothing
  , marketDefinitionSuspendTime = Nothing
  , marketDefinitionDiscountAllowed = Nothing
  , marketDefinitionPersistenceEnabled = Nothing
  , marketDefinitionRunners = Nothing
  , marketDefinitionVersion = Nothing
  , marketDefinitionEventTypeId = Nothing
  , marketDefinitionComplete = Nothing
  , marketDefinitionOpenDate = Nothing
  , marketDefinitionMarketTime = Nothing
  , marketDefinitionBspReconciled = Nothing
  , marketDefinitionLineInterval = Nothing
  , marketDefinitionStatus = Nothing
  }

-- ** MarketFilter
-- | MarketFilter
data MarketFilter = MarketFilter
  { marketFilterCountryCodes      :: !(Maybe [Text]) -- ^ "countryCodes"
  , marketFilterBettingTypes      :: !(Maybe [E'BettingTypes]) -- ^ "bettingTypes"
  , marketFilterTurnInPlayEnabled :: !(Maybe Bool) -- ^ "turnInPlayEnabled"
  , marketFilterMarketTypes       :: !(Maybe [Text]) -- ^ "marketTypes"
  , marketFilterVenues            :: !(Maybe [Text]) -- ^ "venues"
  , marketFilterMarketIds         :: !(Maybe [Text]) -- ^ "marketIds"
  , marketFilterEventTypeIds      :: !(Maybe [Text]) -- ^ "eventTypeIds"
  , marketFilterEventIds          :: !(Maybe [Text]) -- ^ "eventIds"
  , marketFilterBspMarket         :: !(Maybe Bool) -- ^ "bspMarket"
  , marketFilterRaceTypes         :: !(Maybe [Text]) -- ^ "raceTypes"
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON MarketFilter
instance A.FromJSON MarketFilter where
  parseJSON = A.withObject "MarketFilter" $ \o ->
    MarketFilter
      <$> (o .:? "countryCodes")
      <*> (o .:? "bettingTypes")
      <*> (o .:? "turnInPlayEnabled")
      <*> (o .:? "marketTypes")
      <*> (o .:? "venues")
      <*> (o .:? "marketIds")
      <*> (o .:? "eventTypeIds")
      <*> (o .:? "eventIds")
      <*> (o .:? "bspMarket")
      <*> (o .:? "raceTypes")

-- | ToJSON MarketFilter
instance A.ToJSON MarketFilter where
  toJSON MarketFilter {..} =
   _omitNulls
      [ "countryCodes" .= marketFilterCountryCodes
      , "bettingTypes" .= marketFilterBettingTypes
      , "turnInPlayEnabled" .= marketFilterTurnInPlayEnabled
      , "marketTypes" .= marketFilterMarketTypes
      , "venues" .= marketFilterVenues
      , "marketIds" .= marketFilterMarketIds
      , "eventTypeIds" .= marketFilterEventTypeIds
      , "eventIds" .= marketFilterEventIds
      , "bspMarket" .= marketFilterBspMarket
      , "raceTypes" .= marketFilterRaceTypes
      ]


-- | Construct a value of type 'MarketFilter' (by applying it's required fields, if any)
mkMarketFilter
  :: MarketFilter
mkMarketFilter =
  MarketFilter
  { marketFilterCountryCodes = Nothing
  , marketFilterBettingTypes = Nothing
  , marketFilterTurnInPlayEnabled = Nothing
  , marketFilterMarketTypes = Nothing
  , marketFilterVenues = Nothing
  , marketFilterMarketIds = Nothing
  , marketFilterEventTypeIds = Nothing
  , marketFilterEventIds = Nothing
  , marketFilterBspMarket = Nothing
  , marketFilterRaceTypes = Nothing
  }

-- ** Order
-- | Order
data Order = Order
  { orderSide   :: !(Maybe E'Side) -- ^ "side" - Side - the side of the order. For Line markets a &#39;B&#39; bet refers to a SELL line and an &#39;L&#39; bet refers to a BUY line.
  , orderSv     :: !(Maybe Double) -- ^ "sv" - Size Voided - the amount of the order that has been voided
  , orderPt     :: !(Maybe E'Pt) -- ^ "pt" - Persistence Type - whether the order will persist at in play or not (L &#x3D; LAPSE, P &#x3D; PERSIST, MOC &#x3D; Market On Close)
  , orderOt     :: !(Maybe E'Ot) -- ^ "ot" - Order Type - the type of the order (L &#x3D; LIMIT, MOC &#x3D; MARKET_ON_CLOSE, LOC &#x3D; LIMIT_ON_CLOSE)
  , orderP      :: !(Maybe Double) -- ^ "p" - Price - the original placed price of the order. Line markets operate at even-money odds of 2.0. However, price for these markets refers to the line positions available as defined by the markets min-max range and interval steps
  , orderSc     :: !(Maybe Double) -- ^ "sc" - Size Cancelled - the amount of the order that has been cancelled
  , orderRc     :: !(Maybe Text) -- ^ "rc" - Regulator Code - the regulator of the order
  , orderS      :: !(Maybe Double) -- ^ "s" - Size - the original placed size of the order
  , orderPd     :: !(Maybe Integer) -- ^ "pd" - Placed Date - the date the order was placed
  , orderRac    :: !(Maybe Text) -- ^ "rac" - Regulator Auth Code - the auth code returned by the regulator
  , orderMd     :: !(Maybe Integer) -- ^ "md" - Matched Date - the date the order was matched (null if the order is not matched)
  , orderLd     :: !(Maybe Integer) -- ^ "ld" - Lapsed Date - the date the order was lapsed (null if the order is not lapsed)
  , orderSl     :: !(Maybe Double) -- ^ "sl" - Size Lapsed - the amount of the order that has been lapsed
  , orderAvp    :: !(Maybe Double) -- ^ "avp" - Average Price Matched - the average price the order was matched at (null if the order is not matched). This value is not meaningful for activity on Line markets and is not guaranteed to be returned or maintained for these markets.
  , orderSm     :: !(Maybe Double) -- ^ "sm" - Size Matched - the amount of the order that has been matched
  , orderRfo    :: !(Maybe Text) -- ^ "rfo" - Order Reference - the customer&#39;s order reference for this order (empty string if one was not set)
  , orderId     :: !(Maybe Text) -- ^ "id" - Bet Id - the id of the order
  , orderBsp    :: !(Maybe Double) -- ^ "bsp" - BSP Liability - the BSP liability of the order (null if the order is not a BSP order)
  , orderRfs    :: !(Maybe Text) -- ^ "rfs" - Strategy Reference - the customer&#39;s strategy reference for this order (empty string if one was not set)
  , orderStatus :: !(Maybe E'Status3) -- ^ "status" - Status - the status of the order (E &#x3D; EXECUTABLE, EC &#x3D; EXECUTION_COMPLETE)
  , orderSr     :: !(Maybe Double) -- ^ "sr" - Size Remaining - the amount of the order that is remaining unmatched
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON Order
instance A.FromJSON Order where
  parseJSON = A.withObject "Order" $ \o ->
    Order
      <$> (o .:? "side")
      <*> (o .:? "sv")
      <*> (o .:? "pt")
      <*> (o .:? "ot")
      <*> (o .:? "p")
      <*> (o .:? "sc")
      <*> (o .:? "rc")
      <*> (o .:? "s")
      <*> (o .:? "pd")
      <*> (o .:? "rac")
      <*> (o .:? "md")
      <*> (o .:? "ld")
      <*> (o .:? "sl")
      <*> (o .:? "avp")
      <*> (o .:? "sm")
      <*> (o .:? "rfo")
      <*> (o .:? "id")
      <*> (o .:? "bsp")
      <*> (o .:? "rfs")
      <*> (o .:? "status")
      <*> (o .:? "sr")

-- | ToJSON Order
instance A.ToJSON Order where
  toJSON Order {..} =
   _omitNulls
      [ "side" .= orderSide
      , "sv" .= orderSv
      , "pt" .= orderPt
      , "ot" .= orderOt
      , "p" .= orderP
      , "sc" .= orderSc
      , "rc" .= orderRc
      , "s" .= orderS
      , "pd" .= orderPd
      , "rac" .= orderRac
      , "md" .= orderMd
      , "ld" .= orderLd
      , "sl" .= orderSl
      , "avp" .= orderAvp
      , "sm" .= orderSm
      , "rfo" .= orderRfo
      , "id" .= orderId
      , "bsp" .= orderBsp
      , "rfs" .= orderRfs
      , "status" .= orderStatus
      , "sr" .= orderSr
      ]


-- | Construct a value of type 'Order' (by applying it's required fields, if any)
mkOrder
  :: Order
mkOrder =
  Order
  { orderSide = Nothing
  , orderSv = Nothing
  , orderPt = Nothing
  , orderOt = Nothing
  , orderP = Nothing
  , orderSc = Nothing
  , orderRc = Nothing
  , orderS = Nothing
  , orderPd = Nothing
  , orderRac = Nothing
  , orderMd = Nothing
  , orderLd = Nothing
  , orderSl = Nothing
  , orderAvp = Nothing
  , orderSm = Nothing
  , orderRfo = Nothing
  , orderId = Nothing
  , orderBsp = Nothing
  , orderRfs = Nothing
  , orderStatus = Nothing
  , orderSr = Nothing
  }

-- ** OrderFilter
-- | OrderFilter
data OrderFilter = OrderFilter
  { orderFilterIncludeOverallPosition        :: !(Maybe Bool) -- ^ "includeOverallPosition" - Returns overall / net position (See: OrderRunnerChange.mb / OrderRunnerChange.ml). Default&#x3D;true
  , orderFilterAccountIds                    :: !(Maybe [Integer]) -- ^ "accountIds" - Internal use only &amp; should not be set on your filter (your subscription is already locked to your account). If set subscription will fail.
  , orderFilterCustomerStrategyRefs          :: !(Maybe [Text]) -- ^ "customerStrategyRefs" - Restricts to specified customerStrategyRefs; this will filter orders and StrategyMatchChanges accordingly (Note: overall postition is not filtered)
  , orderFilterPartitionMatchedByStrategyRef :: !(Maybe Bool) -- ^ "partitionMatchedByStrategyRef" - Returns strategy positions (See: OrderRunnerChange.smc&#x3D;Map&lt;customerStrategyRef, StrategyMatchChange&gt;) - these are sent in delta format as per overall position. Default&#x3D;false
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON OrderFilter
instance A.FromJSON OrderFilter where
  parseJSON = A.withObject "OrderFilter" $ \o ->
    OrderFilter
      <$> (o .:? "includeOverallPosition")
      <*> (o .:? "accountIds")
      <*> (o .:? "customerStrategyRefs")
      <*> (o .:? "partitionMatchedByStrategyRef")

-- | ToJSON OrderFilter
instance A.ToJSON OrderFilter where
  toJSON OrderFilter {..} =
   _omitNulls
      [ "includeOverallPosition" .= orderFilterIncludeOverallPosition
      , "accountIds" .= orderFilterAccountIds
      , "customerStrategyRefs" .= orderFilterCustomerStrategyRefs
      , "partitionMatchedByStrategyRef" .= orderFilterPartitionMatchedByStrategyRef
      ]


-- | Construct a value of type 'OrderFilter' (by applying it's required fields, if any)
mkOrderFilter
  :: OrderFilter
mkOrderFilter =
  OrderFilter
  { orderFilterIncludeOverallPosition = Nothing
  , orderFilterAccountIds = Nothing
  , orderFilterCustomerStrategyRefs = Nothing
  , orderFilterPartitionMatchedByStrategyRef = Nothing
  }

-- ** OrderMarketChange
-- | OrderMarketChange
data OrderMarketChange = OrderMarketChange
  { orderMarketChangeAccountId :: !(Maybe Integer) -- ^ "accountId"
  , orderMarketChangeOrc       :: !(Maybe [OrderRunnerChange]) -- ^ "orc" - Order Changes - a list of changes to orders on a selection
  , orderMarketChangeClosed    :: !(Maybe Bool) -- ^ "closed"
  , orderMarketChangeId        :: !(Maybe Text) -- ^ "id" - Market Id - the id of the market the order is on
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON OrderMarketChange
instance A.FromJSON OrderMarketChange where
  parseJSON = A.withObject "OrderMarketChange" $ \o ->
    OrderMarketChange
      <$> (o .:? "accountId")
      <*> (o .:? "orc")
      <*> (o .:? "closed")
      <*> (o .:? "id")

-- | ToJSON OrderMarketChange
instance A.ToJSON OrderMarketChange where
  toJSON OrderMarketChange {..} =
   _omitNulls
      [ "accountId" .= orderMarketChangeAccountId
      , "orc" .= orderMarketChangeOrc
      , "closed" .= orderMarketChangeClosed
      , "id" .= orderMarketChangeId
      ]


-- | Construct a value of type 'OrderMarketChange' (by applying it's required fields, if any)
mkOrderMarketChange
  :: OrderMarketChange
mkOrderMarketChange =
  OrderMarketChange
  { orderMarketChangeAccountId = Nothing
  , orderMarketChangeOrc = Nothing
  , orderMarketChangeClosed = Nothing
  , orderMarketChangeId = Nothing
  }

-- ** OrderRunnerChange
-- | OrderRunnerChange
data OrderRunnerChange = OrderRunnerChange
  { orderRunnerChangeMb        :: !(Maybe [[Double]]) -- ^ "mb" - Matched Backs - matched amounts by distinct matched price on the Back side for this runner (selection)
  , orderRunnerChangeSmc       :: !(Maybe (Map.Map String StrategyMatchChange)) -- ^ "smc" - Strategy Matches - Matched Backs and Matched Lays grouped by strategy reference
  , orderRunnerChangeUo        :: !(Maybe [Order]) -- ^ "uo" - Unmatched Orders - orders on this runner (selection) that are not fully matched
  , orderRunnerChangeId        :: !(Maybe Integer) -- ^ "id" - Selection Id - the id of the runner (selection)
  , orderRunnerChangeHc        :: !(Maybe Double) -- ^ "hc" - Handicap - the handicap of the runner (selection) (null if not applicable)
  , orderRunnerChangeFullImage :: !(Maybe Bool) -- ^ "fullImage"
  , orderRunnerChangeMl        :: !(Maybe [[Double]]) -- ^ "ml" - Matched Lays - matched amounts by distinct matched price on the Lay side for this runner (selection)
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON OrderRunnerChange
instance A.FromJSON OrderRunnerChange where
  parseJSON = A.withObject "OrderRunnerChange" $ \o ->
    OrderRunnerChange
      <$> (o .:? "mb")
      <*> (o .:? "smc")
      <*> (o .:? "uo")
      <*> (o .:? "id")
      <*> (o .:? "hc")
      <*> (o .:? "fullImage")
      <*> (o .:? "ml")

-- | ToJSON OrderRunnerChange
instance A.ToJSON OrderRunnerChange where
  toJSON OrderRunnerChange {..} =
   _omitNulls
      [ "mb" .= orderRunnerChangeMb
      , "smc" .= orderRunnerChangeSmc
      , "uo" .= orderRunnerChangeUo
      , "id" .= orderRunnerChangeId
      , "hc" .= orderRunnerChangeHc
      , "fullImage" .= orderRunnerChangeFullImage
      , "ml" .= orderRunnerChangeMl
      ]


-- | Construct a value of type 'OrderRunnerChange' (by applying it's required fields, if any)
mkOrderRunnerChange
  :: OrderRunnerChange
mkOrderRunnerChange =
  OrderRunnerChange
  { orderRunnerChangeMb = Nothing
  , orderRunnerChangeSmc = Nothing
  , orderRunnerChangeUo = Nothing
  , orderRunnerChangeId = Nothing
  , orderRunnerChangeHc = Nothing
  , orderRunnerChangeFullImage = Nothing
  , orderRunnerChangeMl = Nothing
  }

-- ** PriceLadderDefinition
-- | PriceLadderDefinition
data PriceLadderDefinition = PriceLadderDefinition
  { priceLadderDefinitionType :: !(Maybe E'Type) -- ^ "type"
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON PriceLadderDefinition
instance A.FromJSON PriceLadderDefinition where
  parseJSON = A.withObject "PriceLadderDefinition" $ \o ->
    PriceLadderDefinition
      <$> (o .:? "type")

-- | ToJSON PriceLadderDefinition
instance A.ToJSON PriceLadderDefinition where
  toJSON PriceLadderDefinition {..} =
   _omitNulls
      [ "type" .= priceLadderDefinitionType
      ]


-- | Construct a value of type 'PriceLadderDefinition' (by applying it's required fields, if any)
mkPriceLadderDefinition
  :: PriceLadderDefinition
mkPriceLadderDefinition =
  PriceLadderDefinition
  { priceLadderDefinitionType = Nothing
  }

-- ** RequestMessage
-- | RequestMessage
data RequestMessage = RequestMessage
  { requestMessageOp :: !(Maybe Text) -- ^ "op" - The operation type
  , requestMessageId :: !(Maybe Int) -- ^ "id" - Client generated unique id to link request with response (like json rpc)
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON RequestMessage
instance A.FromJSON RequestMessage where
  parseJSON = A.withObject "RequestMessage" $ \o ->
    RequestMessage
      <$> (o .:? "op")
      <*> (o .:? "id")

-- | ToJSON RequestMessage
instance A.ToJSON RequestMessage where
  toJSON RequestMessage {..} =
   _omitNulls
      [ "op" .= requestMessageOp
      , "id" .= requestMessageId
      ]


-- | Construct a value of type 'RequestMessage' (by applying it's required fields, if any)
mkRequestMessage
  :: RequestMessage
mkRequestMessage =
  RequestMessage
  { requestMessageOp = Nothing
  , requestMessageId = Nothing
  }

-- ** ResponseMessage
-- | ResponseMessage
data ResponseMessage = ResponseMessage
  { responseMessageOp :: !(Maybe Text) -- ^ "op" - The operation type
  , responseMessageId :: !(Maybe Int) -- ^ "id" - Client generated unique id to link request with response (like json rpc)
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON ResponseMessage
instance A.FromJSON ResponseMessage where
  parseJSON = A.withObject "ResponseMessage" $ \o ->
    ResponseMessage
      <$> (o .:? "op")
      <*> (o .:? "id")

-- | ToJSON ResponseMessage
instance A.ToJSON ResponseMessage where
  toJSON ResponseMessage {..} =
   _omitNulls
      [ "op" .= responseMessageOp
      , "id" .= responseMessageId
      ]


-- | Construct a value of type 'ResponseMessage' (by applying it's required fields, if any)
mkResponseMessage
  :: ResponseMessage
mkResponseMessage =
  ResponseMessage
  { responseMessageOp = Nothing
  , responseMessageId = Nothing
  }

-- ** RunnerChange
-- | RunnerChange
data RunnerChange = RunnerChange
  { runnerChangeTv    :: !(Maybe Double) -- ^ "tv" - The total amount matched. This value is truncated at 2dp.
  , runnerChangeBatb  :: !(Maybe [[Double]]) -- ^ "batb" - Best Available To Back - LevelPriceVol triple delta of price changes, keyed by level (0 vol is remove)
  , runnerChangeSpb   :: !(Maybe [[Double]]) -- ^ "spb" - Starting Price Back - PriceVol tuple delta of price changes (0 vol is remove)
  , runnerChangeBdatl :: !(Maybe [[Double]]) -- ^ "bdatl" - Best Display Available To Lay (includes virtual prices)- LevelPriceVol triple delta of price changes, keyed by level (0 vol is remove)
  , runnerChangeTrd   :: !(Maybe [[Double]]) -- ^ "trd" - Traded - PriceVol tuple delta of price changes (0 vol is remove)
  , runnerChangeSpf   :: !(Maybe Double) -- ^ "spf" - Starting Price Far - The far starting price (or null if un-changed)
  , runnerChangeLtp   :: !(Maybe Double) -- ^ "ltp" - Last Traded Price - The last traded price (or null if un-changed)
  , runnerChangeAtb   :: !(Maybe [[Double]]) -- ^ "atb" - Available To Back - PriceVol tuple delta of price changes (0 vol is remove)
  , runnerChangeSpl   :: !(Maybe [[Double]]) -- ^ "spl" - Starting Price Lay - PriceVol tuple delta of price changes (0 vol is remove)
  , runnerChangeSpn   :: !(Maybe Double) -- ^ "spn" - Starting Price Near - The far starting price (or null if un-changed)
  , runnerChangeAtl   :: !(Maybe [[Double]]) -- ^ "atl" - Available To Lay - PriceVol tuple delta of price changes (0 vol is remove)
  , runnerChangeBatl  :: !(Maybe [[Double]]) -- ^ "batl" - Best Available To Lay - LevelPriceVol triple delta of price changes, keyed by level (0 vol is remove)
  , runnerChangeId    :: !(Maybe Integer) -- ^ "id" - Selection Id - the id of the runner (selection)
  , runnerChangeHc    :: !(Maybe Double) -- ^ "hc" - Handicap - the handicap of the runner (selection) (null if not applicable)
  , runnerChangeBdatb :: !(Maybe [[Double]]) -- ^ "bdatb" - Best Display Available To Back (includes virtual prices)- LevelPriceVol triple delta of price changes, keyed by level (0 vol is remove)
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON RunnerChange
instance A.FromJSON RunnerChange where
  parseJSON = A.withObject "RunnerChange" $ \o ->
    RunnerChange
      <$> (o .:? "tv")
      <*> (o .:? "batb")
      <*> (o .:? "spb")
      <*> (o .:? "bdatl")
      <*> (o .:? "trd")
      <*> (o .:? "spf")
      <*> (o .:? "ltp")
      <*> (o .:? "atb")
      <*> (o .:? "spl")
      <*> (o .:? "spn")
      <*> (o .:? "atl")
      <*> (o .:? "batl")
      <*> (o .:? "id")
      <*> (o .:? "hc")
      <*> (o .:? "bdatb")

-- | ToJSON RunnerChange
instance A.ToJSON RunnerChange where
  toJSON RunnerChange {..} =
   _omitNulls
      [ "tv" .= runnerChangeTv
      , "batb" .= runnerChangeBatb
      , "spb" .= runnerChangeSpb
      , "bdatl" .= runnerChangeBdatl
      , "trd" .= runnerChangeTrd
      , "spf" .= runnerChangeSpf
      , "ltp" .= runnerChangeLtp
      , "atb" .= runnerChangeAtb
      , "spl" .= runnerChangeSpl
      , "spn" .= runnerChangeSpn
      , "atl" .= runnerChangeAtl
      , "batl" .= runnerChangeBatl
      , "id" .= runnerChangeId
      , "hc" .= runnerChangeHc
      , "bdatb" .= runnerChangeBdatb
      ]


-- | Construct a value of type 'RunnerChange' (by applying it's required fields, if any)
mkRunnerChange
  :: RunnerChange
mkRunnerChange =
  RunnerChange
  { runnerChangeTv = Nothing
  , runnerChangeBatb = Nothing
  , runnerChangeSpb = Nothing
  , runnerChangeBdatl = Nothing
  , runnerChangeTrd = Nothing
  , runnerChangeSpf = Nothing
  , runnerChangeLtp = Nothing
  , runnerChangeAtb = Nothing
  , runnerChangeSpl = Nothing
  , runnerChangeSpn = Nothing
  , runnerChangeAtl = Nothing
  , runnerChangeBatl = Nothing
  , runnerChangeId = Nothing
  , runnerChangeHc = Nothing
  , runnerChangeBdatb = Nothing
  }

-- ** RunnerDefinition
-- | RunnerDefinition
data RunnerDefinition = RunnerDefinition
  { runnerDefinitionSortPriority     :: !(Maybe Int) -- ^ "sortPriority"
  , runnerDefinitionRemovalDate      :: !(Maybe DateTime) -- ^ "removalDate"
  , runnerDefinitionId               :: !(Maybe Integer) -- ^ "id" - Selection Id - the id of the runner (selection)
  , runnerDefinitionHc               :: !(Maybe Double) -- ^ "hc" - Handicap - the handicap of the runner (selection) (null if not applicable)
  , runnerDefinitionAdjustmentFactor :: !(Maybe Double) -- ^ "adjustmentFactor"
  , runnerDefinitionBsp              :: !(Maybe Double) -- ^ "bsp"
  , runnerDefinitionStatus           :: !(Maybe E'Status2) -- ^ "status"
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON RunnerDefinition
instance A.FromJSON RunnerDefinition where
  parseJSON = A.withObject "RunnerDefinition" $ \o ->
    RunnerDefinition
      <$> (o .:? "sortPriority")
      <*> (o .:? "removalDate")
      <*> (o .:? "id")
      <*> (o .:? "hc")
      <*> (o .:? "adjustmentFactor")
      <*> (o .:? "bsp")
      <*> (o .:? "status")

-- | ToJSON RunnerDefinition
instance A.ToJSON RunnerDefinition where
  toJSON RunnerDefinition {..} =
   _omitNulls
      [ "sortPriority" .= runnerDefinitionSortPriority
      , "removalDate" .= runnerDefinitionRemovalDate
      , "id" .= runnerDefinitionId
      , "hc" .= runnerDefinitionHc
      , "adjustmentFactor" .= runnerDefinitionAdjustmentFactor
      , "bsp" .= runnerDefinitionBsp
      , "status" .= runnerDefinitionStatus
      ]


-- | Construct a value of type 'RunnerDefinition' (by applying it's required fields, if any)
mkRunnerDefinition
  :: RunnerDefinition
mkRunnerDefinition =
  RunnerDefinition
  { runnerDefinitionSortPriority = Nothing
  , runnerDefinitionRemovalDate = Nothing
  , runnerDefinitionId = Nothing
  , runnerDefinitionHc = Nothing
  , runnerDefinitionAdjustmentFactor = Nothing
  , runnerDefinitionBsp = Nothing
  , runnerDefinitionStatus = Nothing
  }

-- ** StrategyMatchChange
-- | StrategyMatchChange
data StrategyMatchChange = StrategyMatchChange
  { strategyMatchChangeMb :: !(Maybe [[Double]]) -- ^ "mb" - Matched Backs - matched amounts by distinct matched price on the Back side for this strategy
  , strategyMatchChangeMl :: !(Maybe [[Double]]) -- ^ "ml" - Matched Lays - matched amounts by distinct matched price on the Lay side for this strategy
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON StrategyMatchChange
instance A.FromJSON StrategyMatchChange where
  parseJSON = A.withObject "StrategyMatchChange" $ \o ->
    StrategyMatchChange
      <$> (o .:? "mb")
      <*> (o .:? "ml")

-- | ToJSON StrategyMatchChange
instance A.ToJSON StrategyMatchChange where
  toJSON StrategyMatchChange {..} =
   _omitNulls
      [ "mb" .= strategyMatchChangeMb
      , "ml" .= strategyMatchChangeMl
      ]


-- | Construct a value of type 'StrategyMatchChange' (by applying it's required fields, if any)
mkStrategyMatchChange
  :: StrategyMatchChange
mkStrategyMatchChange =
  StrategyMatchChange
  { strategyMatchChangeMb = Nothing
  , strategyMatchChangeMl = Nothing
  }

-- ** AuthenticationMessage
-- | AuthenticationMessage
data AuthenticationMessage = AuthenticationMessage
  { authenticationMessageOp      :: !(Maybe Text) -- ^ "op" - The operation type
  , authenticationMessageId      :: !(Maybe Int) -- ^ "id" - Client generated unique id to link request with response (like json rpc)
  , authenticationMessageSession :: !(Maybe Text) -- ^ "session"
  , authenticationMessageAppKey  :: !(Maybe Text) -- ^ "appKey"
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON AuthenticationMessage
instance A.FromJSON AuthenticationMessage where
  parseJSON = A.withObject "AuthenticationMessage" $ \o ->
    AuthenticationMessage
      <$> (o .:? "op")
      <*> (o .:? "id")
      <*> (o .:? "session")
      <*> (o .:? "appKey")

-- | ToJSON AuthenticationMessage
instance A.ToJSON AuthenticationMessage where
  toJSON AuthenticationMessage {..} =
   _omitNulls
      [ "op" .= authenticationMessageOp
      , "id" .= authenticationMessageId
      , "session" .= authenticationMessageSession
      , "appKey" .= authenticationMessageAppKey
      ]


-- | Construct a value of type 'AuthenticationMessage' (by applying it's required fields, if any)
mkAuthenticationMessage
  :: AuthenticationMessage
mkAuthenticationMessage =
  AuthenticationMessage
  { authenticationMessageOp = Just "authentication"
  , authenticationMessageId = Nothing
  , authenticationMessageSession = Nothing
  , authenticationMessageAppKey = Nothing
  }

-- ** ConnectionMessage
-- | ConnectionMessage
data ConnectionMessage = ConnectionMessage
  { connectionMessageOp           :: !(Maybe Text) -- ^ "op" - The operation type
  , connectionMessageId           :: !(Maybe Int) -- ^ "id" - Client generated unique id to link request with response (like json rpc)
  , connectionMessageConnectionId :: !(Maybe Text) -- ^ "connectionId" - The connection id
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON ConnectionMessage
instance A.FromJSON ConnectionMessage where
  parseJSON = A.withObject "ConnectionMessage" $ \o ->
    ConnectionMessage
      <$> (o .:? "op")
      <*> (o .:? "id")
      <*> (o .:? "connectionId")

-- | ToJSON ConnectionMessage
instance A.ToJSON ConnectionMessage where
  toJSON ConnectionMessage {..} =
   _omitNulls
      [ "op" .= connectionMessageOp
      , "id" .= connectionMessageId
      , "connectionId" .= connectionMessageConnectionId
      ]


-- | Construct a value of type 'ConnectionMessage' (by applying it's required fields, if any)
mkConnectionMessage
  :: ConnectionMessage
mkConnectionMessage =
  ConnectionMessage
  { connectionMessageOp = Nothing
  , connectionMessageId = Nothing
  , connectionMessageConnectionId = Nothing
  }

-- ** HeartbeatMessage
-- | HeartbeatMessage
data HeartbeatMessage = HeartbeatMessage
  { heartbeatMessageOp :: !(Maybe Text) -- ^ "op" - The operation type
  , heartbeatMessageId :: !(Maybe Int) -- ^ "id" - Client generated unique id to link request with response (like json rpc)
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON HeartbeatMessage
instance A.FromJSON HeartbeatMessage where
  parseJSON = A.withObject "HeartbeatMessage" $ \o ->
    HeartbeatMessage
      <$> (o .:? "op")
      <*> (o .:? "id")

-- | ToJSON HeartbeatMessage
instance A.ToJSON HeartbeatMessage where
  toJSON HeartbeatMessage {..} =
   _omitNulls
      [ "op" .= heartbeatMessageOp
      , "id" .= heartbeatMessageId
      ]


-- | Construct a value of type 'HeartbeatMessage' (by applying it's required fields, if any)
mkHeartbeatMessage
  :: HeartbeatMessage
mkHeartbeatMessage =
  HeartbeatMessage
  { heartbeatMessageOp = Nothing
  , heartbeatMessageId = Nothing
  }

-- ** MarketChangeMessage
-- | MarketChangeMessage
data MarketChangeMessage = MarketChangeMessage
  { marketChangeMessageOp          :: !(Maybe Text) -- ^ "op" - The operation type
  , marketChangeMessageId          :: !(Maybe Int) -- ^ "id" - Client generated unique id to link request with response (like json rpc)
  , marketChangeMessageCt          :: !(Maybe E'Ct) -- ^ "ct" - Change Type - set to indicate the type of change - if null this is a delta)
  , marketChangeMessageClk         :: !(Maybe Text) -- ^ "clk" - Token value (non-null) should be stored and passed in a MarketSubscriptionMessage to resume subscription (in case of disconnect)
  , marketChangeMessageHeartbeatMs :: !(Maybe Integer) -- ^ "heartbeatMs" - Heartbeat Milliseconds - the heartbeat rate (may differ from requested: bounds are 500 to 30000)
  , marketChangeMessagePt          :: !(Maybe Integer) -- ^ "pt" - Publish Time (in millis since epoch) that the changes were generated
  , marketChangeMessageInitialClk  :: !(Maybe Text) -- ^ "initialClk" - Token value (non-null) should be stored and passed in a MarketSubscriptionMessage to resume subscription (in case of disconnect)
  , marketChangeMessageMc          :: !(Maybe [MarketChange]) -- ^ "mc" - MarketChanges - the modifications to markets (will be null on a heartbeat
  , marketChangeMessageConflateMs  :: !(Maybe Integer) -- ^ "conflateMs" - Conflate Milliseconds - the conflation rate (may differ from that requested if subscription is delayed)
  , marketChangeMessageSegmentType :: !(Maybe E'SegmentType) -- ^ "segmentType" - Segment Type - if the change is split into multiple segments, this denotes the beginning and end of a change, and segments in between. Will be null if data is not segmented
  , marketChangeMessageStatus      :: !(Maybe Int) -- ^ "status" - Stream status: set to null if the exchange stream data is up to date and 503 if the downstream services are experiencing latencies
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON MarketChangeMessage
instance A.FromJSON MarketChangeMessage where
  parseJSON = A.withObject "MarketChangeMessage" $ \o ->
    MarketChangeMessage
      <$> (o .:? "op")
      <*> (o .:? "id")
      <*> (o .:? "ct")
      <*> (o .:? "clk")
      <*> (o .:? "heartbeatMs")
      <*> (o .:? "pt")
      <*> (o .:? "initialClk")
      <*> (o .:? "mc")
      <*> (o .:? "conflateMs")
      <*> (o .:? "segmentType")
      <*> (o .:? "status")

-- | ToJSON MarketChangeMessage
instance A.ToJSON MarketChangeMessage where
  toJSON MarketChangeMessage {..} =
   _omitNulls
      [ "op" .= marketChangeMessageOp
      , "id" .= marketChangeMessageId
      , "ct" .= marketChangeMessageCt
      , "clk" .= marketChangeMessageClk
      , "heartbeatMs" .= marketChangeMessageHeartbeatMs
      , "pt" .= marketChangeMessagePt
      , "initialClk" .= marketChangeMessageInitialClk
      , "mc" .= marketChangeMessageMc
      , "conflateMs" .= marketChangeMessageConflateMs
      , "segmentType" .= marketChangeMessageSegmentType
      , "status" .= marketChangeMessageStatus
      ]


-- | Construct a value of type 'MarketChangeMessage' (by applying it's required fields, if any)
mkMarketChangeMessage
  :: MarketChangeMessage
mkMarketChangeMessage =
  MarketChangeMessage
  { marketChangeMessageOp = Nothing
  , marketChangeMessageId = Nothing
  , marketChangeMessageCt = Nothing
  , marketChangeMessageClk = Nothing
  , marketChangeMessageHeartbeatMs = Nothing
  , marketChangeMessagePt = Nothing
  , marketChangeMessageInitialClk = Nothing
  , marketChangeMessageMc = Nothing
  , marketChangeMessageConflateMs = Nothing
  , marketChangeMessageSegmentType = Nothing
  , marketChangeMessageStatus = Nothing
  }

-- ** MarketSubscriptionMessage
-- | MarketSubscriptionMessage
data MarketSubscriptionMessage = MarketSubscriptionMessage
  { marketSubscriptionMessageOp                  :: !(Maybe Text) -- ^ "op" - The operation type
  , marketSubscriptionMessageId                  :: !(Maybe Int) -- ^ "id" - Client generated unique id to link request with response (like json rpc)
  , marketSubscriptionMessageSegmentationEnabled :: !(Maybe Bool) -- ^ "segmentationEnabled" - Segmentation Enabled - allow the server to send large sets of data in segments, instead of a single block
  , marketSubscriptionMessageClk                 :: !(Maybe Text) -- ^ "clk" - Token value delta (received in MarketChangeMessage) that should be passed to resume a subscription
  , marketSubscriptionMessageHeartbeatMs         :: !(Maybe Integer) -- ^ "heartbeatMs" - Heartbeat Milliseconds - the heartbeat rate (looped back on initial image after validation: bounds are 500 to 5000)
  , marketSubscriptionMessageInitialClk          :: !(Maybe Text) -- ^ "initialClk" - Token value (received in initial MarketChangeMessage) that should be passed to resume a subscription
  , marketSubscriptionMessageMarketFilter        :: !(Maybe MarketFilter) -- ^ "marketFilter"
  , marketSubscriptionMessageConflateMs          :: !(Maybe Integer) -- ^ "conflateMs" - Conflate Milliseconds - the conflation rate (looped back on initial image after validation: bounds are 0 to 120000)
  , marketSubscriptionMessageMarketDataFilter    :: !(Maybe MarketDataFilter) -- ^ "marketDataFilter"
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON MarketSubscriptionMessage
instance A.FromJSON MarketSubscriptionMessage where
  parseJSON = A.withObject "MarketSubscriptionMessage" $ \o ->
    MarketSubscriptionMessage
      <$> (o .:? "op")
      <*> (o .:? "id")
      <*> (o .:? "segmentationEnabled")
      <*> (o .:? "clk")
      <*> (o .:? "heartbeatMs")
      <*> (o .:? "initialClk")
      <*> (o .:? "marketFilter")
      <*> (o .:? "conflateMs")
      <*> (o .:? "marketDataFilter")

-- | ToJSON MarketSubscriptionMessage
instance A.ToJSON MarketSubscriptionMessage where
  toJSON MarketSubscriptionMessage {..} =
   _omitNulls
      [ "op" .= marketSubscriptionMessageOp
      , "id" .= marketSubscriptionMessageId
      , "segmentationEnabled" .= marketSubscriptionMessageSegmentationEnabled
      , "clk" .= marketSubscriptionMessageClk
      , "heartbeatMs" .= marketSubscriptionMessageHeartbeatMs
      , "initialClk" .= marketSubscriptionMessageInitialClk
      , "marketFilter" .= marketSubscriptionMessageMarketFilter
      , "conflateMs" .= marketSubscriptionMessageConflateMs
      , "marketDataFilter" .= marketSubscriptionMessageMarketDataFilter
      ]


-- | Construct a value of type 'MarketSubscriptionMessage' (by applying it's required fields, if any)
mkMarketSubscriptionMessage
  :: MarketSubscriptionMessage
mkMarketSubscriptionMessage =
  MarketSubscriptionMessage
  { marketSubscriptionMessageOp = Just "marketSubscription"
  , marketSubscriptionMessageId = Nothing
  , marketSubscriptionMessageSegmentationEnabled = Nothing
  , marketSubscriptionMessageClk = Nothing
  , marketSubscriptionMessageHeartbeatMs = Nothing
  , marketSubscriptionMessageInitialClk = Nothing
  , marketSubscriptionMessageMarketFilter = Nothing
  , marketSubscriptionMessageConflateMs = Nothing
  , marketSubscriptionMessageMarketDataFilter = Nothing
  }

-- ** OrderChangeMessage
-- | OrderChangeMessage
data OrderChangeMessage = OrderChangeMessage
  { orderChangeMessageOp          :: !(Maybe Text) -- ^ "op" - The operation type
  , orderChangeMessageId          :: !(Maybe Int) -- ^ "id" - Client generated unique id to link request with response (like json rpc)
  , orderChangeMessageCt          :: !(Maybe E'Ct) -- ^ "ct" - Change Type - set to indicate the type of change - if null this is a delta)
  , orderChangeMessageClk         :: !(Maybe Text) -- ^ "clk" - Token value (non-null) should be stored and passed in a MarketSubscriptionMessage to resume subscription (in case of disconnect)
  , orderChangeMessageHeartbeatMs :: !(Maybe Integer) -- ^ "heartbeatMs" - Heartbeat Milliseconds - the heartbeat rate (may differ from requested: bounds are 500 to 30000)
  , orderChangeMessagePt          :: !(Maybe Integer) -- ^ "pt" - Publish Time (in millis since epoch) that the changes were generated
  , orderChangeMessageOc          :: !(Maybe [OrderMarketChange]) -- ^ "oc" - OrderMarketChanges - the modifications to account&#39;s orders (will be null on a heartbeat
  , orderChangeMessageInitialClk  :: !(Maybe Text) -- ^ "initialClk" - Token value (non-null) should be stored and passed in a MarketSubscriptionMessage to resume subscription (in case of disconnect)
  , orderChangeMessageConflateMs  :: !(Maybe Integer) -- ^ "conflateMs" - Conflate Milliseconds - the conflation rate (may differ from that requested if subscription is delayed)
  , orderChangeMessageSegmentType :: !(Maybe E'SegmentType) -- ^ "segmentType" - Segment Type - if the change is split into multiple segments, this denotes the beginning and end of a change, and segments in between. Will be null if data is not segmented
  , orderChangeMessageStatus      :: !(Maybe Int) -- ^ "status" - Stream status: set to null if the exchange stream data is up to date and 503 if the downstream services are experiencing latencies
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON OrderChangeMessage
instance A.FromJSON OrderChangeMessage where
  parseJSON = A.withObject "OrderChangeMessage" $ \o ->
    OrderChangeMessage
      <$> (o .:? "op")
      <*> (o .:? "id")
      <*> (o .:? "ct")
      <*> (o .:? "clk")
      <*> (o .:? "heartbeatMs")
      <*> (o .:? "pt")
      <*> (o .:? "oc")
      <*> (o .:? "initialClk")
      <*> (o .:? "conflateMs")
      <*> (o .:? "segmentType")
      <*> (o .:? "status")

-- | ToJSON OrderChangeMessage
instance A.ToJSON OrderChangeMessage where
  toJSON OrderChangeMessage {..} =
   _omitNulls
      [ "op" .= orderChangeMessageOp
      , "id" .= orderChangeMessageId
      , "ct" .= orderChangeMessageCt
      , "clk" .= orderChangeMessageClk
      , "heartbeatMs" .= orderChangeMessageHeartbeatMs
      , "pt" .= orderChangeMessagePt
      , "oc" .= orderChangeMessageOc
      , "initialClk" .= orderChangeMessageInitialClk
      , "conflateMs" .= orderChangeMessageConflateMs
      , "segmentType" .= orderChangeMessageSegmentType
      , "status" .= orderChangeMessageStatus
      ]


-- | Construct a value of type 'OrderChangeMessage' (by applying it's required fields, if any)
mkOrderChangeMessage
  :: OrderChangeMessage
mkOrderChangeMessage =
  OrderChangeMessage
  { orderChangeMessageOp = Nothing
  , orderChangeMessageId = Nothing
  , orderChangeMessageCt = Nothing
  , orderChangeMessageClk = Nothing
  , orderChangeMessageHeartbeatMs = Nothing
  , orderChangeMessagePt = Nothing
  , orderChangeMessageOc = Nothing
  , orderChangeMessageInitialClk = Nothing
  , orderChangeMessageConflateMs = Nothing
  , orderChangeMessageSegmentType = Nothing
  , orderChangeMessageStatus = Nothing
  }

-- ** OrderSubscriptionMessage
-- | OrderSubscriptionMessage
data OrderSubscriptionMessage = OrderSubscriptionMessage
  { orderSubscriptionMessageOp                  :: !(Maybe Text) -- ^ "op" - The operation type
  , orderSubscriptionMessageId                  :: !(Maybe Int) -- ^ "id" - Client generated unique id to link request with response (like json rpc)
  , orderSubscriptionMessageSegmentationEnabled :: !(Maybe Bool) -- ^ "segmentationEnabled" - Segmentation Enabled - allow the server to send large sets of data in segments, instead of a single block
  , orderSubscriptionMessageOrderFilter         :: !(Maybe OrderFilter) -- ^ "orderFilter" - Optional filter applied to order subscription
  , orderSubscriptionMessageClk                 :: !(Maybe Text) -- ^ "clk" - Token value delta (received in MarketChangeMessage) that should be passed to resume a subscription
  , orderSubscriptionMessageHeartbeatMs         :: !(Maybe Integer) -- ^ "heartbeatMs" - Heartbeat Milliseconds - the heartbeat rate (looped back on initial image after validation: bounds are 500 to 5000)
  , orderSubscriptionMessageInitialClk          :: !(Maybe Text) -- ^ "initialClk" - Token value (received in initial MarketChangeMessage) that should be passed to resume a subscription
  , orderSubscriptionMessageConflateMs          :: !(Maybe Integer) -- ^ "conflateMs" - Conflate Milliseconds - the conflation rate (looped back on initial image after validation: bounds are 0 to 120000)
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON OrderSubscriptionMessage
instance A.FromJSON OrderSubscriptionMessage where
  parseJSON = A.withObject "OrderSubscriptionMessage" $ \o ->
    OrderSubscriptionMessage
      <$> (o .:? "op")
      <*> (o .:? "id")
      <*> (o .:? "segmentationEnabled")
      <*> (o .:? "orderFilter")
      <*> (o .:? "clk")
      <*> (o .:? "heartbeatMs")
      <*> (o .:? "initialClk")
      <*> (o .:? "conflateMs")

-- | ToJSON OrderSubscriptionMessage
instance A.ToJSON OrderSubscriptionMessage where
  toJSON OrderSubscriptionMessage {..} =
   _omitNulls
      [ "op" .= orderSubscriptionMessageOp
      , "id" .= orderSubscriptionMessageId
      , "segmentationEnabled" .= orderSubscriptionMessageSegmentationEnabled
      , "orderFilter" .= orderSubscriptionMessageOrderFilter
      , "clk" .= orderSubscriptionMessageClk
      , "heartbeatMs" .= orderSubscriptionMessageHeartbeatMs
      , "initialClk" .= orderSubscriptionMessageInitialClk
      , "conflateMs" .= orderSubscriptionMessageConflateMs
      ]

-- | Construct a value of type 'OrderSubscriptionMessage' (by applying it's required fields, if any)
mkOrderSubscriptionMessage
  :: OrderSubscriptionMessage
mkOrderSubscriptionMessage =
  OrderSubscriptionMessage
  { orderSubscriptionMessageOp = Just "orderSubscription"
  , orderSubscriptionMessageId = Nothing
  , orderSubscriptionMessageSegmentationEnabled = Nothing
  , orderSubscriptionMessageOrderFilter = Nothing
  , orderSubscriptionMessageClk = Nothing
  , orderSubscriptionMessageHeartbeatMs = Nothing
  , orderSubscriptionMessageInitialClk = Nothing
  , orderSubscriptionMessageConflateMs = Nothing
  }

-- ** StatusMessage
-- | StatusMessage
data StatusMessage = StatusMessage
  { statusMessageOp               :: !(Maybe Text) -- ^ "op" - The operation type
  , statusMessageId               :: !(Maybe Int) -- ^ "id" - Client generated unique id to link request with response (like json rpc)
  , statusMessageErrorMessage     :: !(Maybe Text) -- ^ "errorMessage" - Additional message in case of a failure
  , statusMessageErrorCode        :: !(Maybe E'ErrorCode) -- ^ "errorCode" - The type of error in case of a failure
  , statusMessageConnectionId     :: !(Maybe Text) -- ^ "connectionId" - The connection id
  , statusMessageConnectionClosed :: !(Maybe Bool) -- ^ "connectionClosed" - Is the connection now closed
  , statusMessageStatusCode       :: !(Maybe E'StatusCode) -- ^ "statusCode" - The status of the last request
  } deriving (P.Show, P.Eq, P.Typeable)

-- | FromJSON StatusMessage
instance A.FromJSON StatusMessage where
  parseJSON = A.withObject "StatusMessage" $ \o ->
    StatusMessage
      <$> (o .:? "op")
      <*> (o .:? "id")
      <*> (o .:? "errorMessage")
      <*> (o .:? "errorCode")
      <*> (o .:? "connectionId")
      <*> (o .:? "connectionClosed")
      <*> (o .:? "statusCode")

-- | ToJSON StatusMessage
instance A.ToJSON StatusMessage where
  toJSON StatusMessage {..} =
   _omitNulls
      [ "op" .= statusMessageOp
      , "id" .= statusMessageId
      , "errorMessage" .= statusMessageErrorMessage
      , "errorCode" .= statusMessageErrorCode
      , "connectionId" .= statusMessageConnectionId
      , "connectionClosed" .= statusMessageConnectionClosed
      , "statusCode" .= statusMessageStatusCode
      ]


-- | Construct a value of type 'StatusMessage' (by applying it's required fields, if any)
mkStatusMessage
  :: StatusMessage
mkStatusMessage =
  StatusMessage
  { statusMessageOp = Nothing
  , statusMessageId = Nothing
  , statusMessageErrorMessage = Nothing
  , statusMessageErrorCode = Nothing
  , statusMessageConnectionId = Nothing
  , statusMessageConnectionClosed = Nothing
  , statusMessageStatusCode = Nothing
  }


-- * Enums


-- ** E'BettingTypes

-- | Enum of 'Text'
data E'BettingTypes
  = E'BettingTypes'ODDS -- ^ @"ODDS"@
  | E'BettingTypes'LINE -- ^ @"LINE"@
  | E'BettingTypes'RANGE -- ^ @"RANGE"@
  | E'BettingTypes'ASIAN_HANDICAP_DOUBLE_LINE -- ^ @"ASIAN_HANDICAP_DOUBLE_LINE"@
  | E'BettingTypes'ASIAN_HANDICAP_SINGLE_LINE -- ^ @"ASIAN_HANDICAP_SINGLE_LINE"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'BettingTypes where toJSON = A.toJSON . fromE'BettingTypes
instance A.FromJSON E'BettingTypes where parseJSON o = P.either P.fail (pure . P.id) . toE'BettingTypes =<< A.parseJSON o

-- | unwrap 'E'BettingTypes' enum
fromE'BettingTypes :: E'BettingTypes -> Text
fromE'BettingTypes = \case
  E'BettingTypes'ODDS -> "ODDS"
  E'BettingTypes'LINE -> "LINE"
  E'BettingTypes'RANGE -> "RANGE"
  E'BettingTypes'ASIAN_HANDICAP_DOUBLE_LINE -> "ASIAN_HANDICAP_DOUBLE_LINE"
  E'BettingTypes'ASIAN_HANDICAP_SINGLE_LINE -> "ASIAN_HANDICAP_SINGLE_LINE"

-- | parse 'E'BettingTypes' enum
toE'BettingTypes :: Text -> P.Either String E'BettingTypes
toE'BettingTypes = \case
  "ODDS" -> P.Right E'BettingTypes'ODDS
  "LINE" -> P.Right E'BettingTypes'LINE
  "RANGE" -> P.Right E'BettingTypes'RANGE
  "ASIAN_HANDICAP_DOUBLE_LINE" -> P.Right E'BettingTypes'ASIAN_HANDICAP_DOUBLE_LINE
  "ASIAN_HANDICAP_SINGLE_LINE" -> P.Right E'BettingTypes'ASIAN_HANDICAP_SINGLE_LINE
  s -> P.Left $ "toE'BettingTypes: enum parse failure: " P.++ P.show s


-- ** E'Ct

-- | Enum of 'Text' .
-- Change Type - set to indicate the type of change - if null this is a delta)
data E'Ct
  = E'Ct'SUB_IMAGE -- ^ @"SUB_IMAGE"@
  | E'Ct'RESUB_DELTA -- ^ @"RESUB_DELTA"@
  | E'Ct'HEARTBEAT -- ^ @"HEARTBEAT"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'Ct where toJSON = A.toJSON . fromE'Ct
instance A.FromJSON E'Ct where parseJSON o = P.either P.fail (pure . P.id) . toE'Ct =<< A.parseJSON o

-- | unwrap 'E'Ct' enum
fromE'Ct :: E'Ct -> Text
fromE'Ct = \case
  E'Ct'SUB_IMAGE -> "SUB_IMAGE"
  E'Ct'RESUB_DELTA -> "RESUB_DELTA"
  E'Ct'HEARTBEAT -> "HEARTBEAT"

-- | parse 'E'Ct' enum
toE'Ct :: Text -> P.Either String E'Ct
toE'Ct = \case
  "SUB_IMAGE" -> P.Right E'Ct'SUB_IMAGE
  "RESUB_DELTA" -> P.Right E'Ct'RESUB_DELTA
  "HEARTBEAT" -> P.Right E'Ct'HEARTBEAT
  s -> P.Left $ "toE'Ct: enum parse failure: " P.++ P.show s


-- ** E'ErrorCode

-- | Enum of 'Text' .
-- The type of error in case of a failure
data E'ErrorCode
  = E'ErrorCode'NO_APP_KEY -- ^ @"NO_APP_KEY"@
  | E'ErrorCode'INVALID_APP_KEY -- ^ @"INVALID_APP_KEY"@
  | E'ErrorCode'NO_SESSION -- ^ @"NO_SESSION"@
  | E'ErrorCode'INVALID_SESSION_INFORMATION -- ^ @"INVALID_SESSION_INFORMATION"@
  | E'ErrorCode'NOT_AUTHORIZED -- ^ @"NOT_AUTHORIZED"@
  | E'ErrorCode'INVALID_INPUT -- ^ @"INVALID_INPUT"@
  | E'ErrorCode'INVALID_CLOCK -- ^ @"INVALID_CLOCK"@
  | E'ErrorCode'UNEXPECTED_ERROR -- ^ @"UNEXPECTED_ERROR"@
  | E'ErrorCode'TIMEOUT -- ^ @"TIMEOUT"@
  | E'ErrorCode'SUBSCRIPTION_LIMIT_EXCEEDED -- ^ @"SUBSCRIPTION_LIMIT_EXCEEDED"@
  | E'ErrorCode'INVALID_REQUEST -- ^ @"INVALID_REQUEST"@
  | E'ErrorCode'CONNECTION_FAILED -- ^ @"CONNECTION_FAILED"@
  | E'ErrorCode'MAX_CONNECTION_LIMIT_EXCEEDED -- ^ @"MAX_CONNECTION_LIMIT_EXCEEDED"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'ErrorCode where toJSON = A.toJSON . fromE'ErrorCode
instance A.FromJSON E'ErrorCode where parseJSON o = P.either P.fail (pure . P.id) . toE'ErrorCode =<< A.parseJSON o

-- | unwrap 'E'ErrorCode' enum
fromE'ErrorCode :: E'ErrorCode -> Text
fromE'ErrorCode = \case
  E'ErrorCode'NO_APP_KEY -> "NO_APP_KEY"
  E'ErrorCode'INVALID_APP_KEY -> "INVALID_APP_KEY"
  E'ErrorCode'NO_SESSION -> "NO_SESSION"
  E'ErrorCode'INVALID_SESSION_INFORMATION -> "INVALID_SESSION_INFORMATION"
  E'ErrorCode'NOT_AUTHORIZED -> "NOT_AUTHORIZED"
  E'ErrorCode'INVALID_INPUT -> "INVALID_INPUT"
  E'ErrorCode'INVALID_CLOCK -> "INVALID_CLOCK"
  E'ErrorCode'UNEXPECTED_ERROR -> "UNEXPECTED_ERROR"
  E'ErrorCode'TIMEOUT -> "TIMEOUT"
  E'ErrorCode'SUBSCRIPTION_LIMIT_EXCEEDED -> "SUBSCRIPTION_LIMIT_EXCEEDED"
  E'ErrorCode'INVALID_REQUEST -> "INVALID_REQUEST"
  E'ErrorCode'CONNECTION_FAILED -> "CONNECTION_FAILED"
  E'ErrorCode'MAX_CONNECTION_LIMIT_EXCEEDED -> "MAX_CONNECTION_LIMIT_EXCEEDED"

-- | parse 'E'ErrorCode' enum
toE'ErrorCode :: Text -> P.Either String E'ErrorCode
toE'ErrorCode = \case
  "NO_APP_KEY" -> P.Right E'ErrorCode'NO_APP_KEY
  "INVALID_APP_KEY" -> P.Right E'ErrorCode'INVALID_APP_KEY
  "NO_SESSION" -> P.Right E'ErrorCode'NO_SESSION
  "INVALID_SESSION_INFORMATION" -> P.Right E'ErrorCode'INVALID_SESSION_INFORMATION
  "NOT_AUTHORIZED" -> P.Right E'ErrorCode'NOT_AUTHORIZED
  "INVALID_INPUT" -> P.Right E'ErrorCode'INVALID_INPUT
  "INVALID_CLOCK" -> P.Right E'ErrorCode'INVALID_CLOCK
  "UNEXPECTED_ERROR" -> P.Right E'ErrorCode'UNEXPECTED_ERROR
  "TIMEOUT" -> P.Right E'ErrorCode'TIMEOUT
  "SUBSCRIPTION_LIMIT_EXCEEDED" -> P.Right E'ErrorCode'SUBSCRIPTION_LIMIT_EXCEEDED
  "INVALID_REQUEST" -> P.Right E'ErrorCode'INVALID_REQUEST
  "CONNECTION_FAILED" -> P.Right E'ErrorCode'CONNECTION_FAILED
  "MAX_CONNECTION_LIMIT_EXCEEDED" -> P.Right E'ErrorCode'MAX_CONNECTION_LIMIT_EXCEEDED
  s -> P.Left $ "toE'ErrorCode: enum parse failure: " P.++ P.show s


-- ** E'Fields

-- | Enum of 'Text'
data E'Fields
  = E'Fields'EX_BEST_OFFERS_DISP -- ^ @"EX_BEST_OFFERS_DISP"@
  | E'Fields'EX_BEST_OFFERS -- ^ @"EX_BEST_OFFERS"@
  | E'Fields'EX_ALL_OFFERS -- ^ @"EX_ALL_OFFERS"@
  | E'Fields'EX_TRADED -- ^ @"EX_TRADED"@
  | E'Fields'EX_TRADED_VOL -- ^ @"EX_TRADED_VOL"@
  | E'Fields'EX_LTP -- ^ @"EX_LTP"@
  | E'Fields'EX_MARKET_DEF -- ^ @"EX_MARKET_DEF"@
  | E'Fields'SP_TRADED -- ^ @"SP_TRADED"@
  | E'Fields'SP_PROJECTED -- ^ @"SP_PROJECTED"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'Fields where toJSON = A.toJSON . fromE'Fields
instance A.FromJSON E'Fields where parseJSON o = P.either P.fail (pure . P.id) . toE'Fields =<< A.parseJSON o

-- | unwrap 'E'Fields' enum
fromE'Fields :: E'Fields -> Text
fromE'Fields = \case
  E'Fields'EX_BEST_OFFERS_DISP -> "EX_BEST_OFFERS_DISP"
  E'Fields'EX_BEST_OFFERS -> "EX_BEST_OFFERS"
  E'Fields'EX_ALL_OFFERS -> "EX_ALL_OFFERS"
  E'Fields'EX_TRADED -> "EX_TRADED"
  E'Fields'EX_TRADED_VOL -> "EX_TRADED_VOL"
  E'Fields'EX_LTP -> "EX_LTP"
  E'Fields'EX_MARKET_DEF -> "EX_MARKET_DEF"
  E'Fields'SP_TRADED -> "SP_TRADED"
  E'Fields'SP_PROJECTED -> "SP_PROJECTED"

-- | parse 'E'Fields' enum
toE'Fields :: Text -> P.Either String E'Fields
toE'Fields = \case
  "EX_BEST_OFFERS_DISP" -> P.Right E'Fields'EX_BEST_OFFERS_DISP
  "EX_BEST_OFFERS" -> P.Right E'Fields'EX_BEST_OFFERS
  "EX_ALL_OFFERS" -> P.Right E'Fields'EX_ALL_OFFERS
  "EX_TRADED" -> P.Right E'Fields'EX_TRADED
  "EX_TRADED_VOL" -> P.Right E'Fields'EX_TRADED_VOL
  "EX_LTP" -> P.Right E'Fields'EX_LTP
  "EX_MARKET_DEF" -> P.Right E'Fields'EX_MARKET_DEF
  "SP_TRADED" -> P.Right E'Fields'SP_TRADED
  "SP_PROJECTED" -> P.Right E'Fields'SP_PROJECTED
  s -> P.Left $ "toE'Fields: enum parse failure: " P.++ P.show s


-- ** E'OpTypes

-- | Enum of 'Text'
data E'OpTypes
  = E'OpTypes'Heartbeat -- ^ @"heartbeat"@
  | E'OpTypes'Authentication -- ^ @"authentication"@
  | E'OpTypes'MarketSubscription -- ^ @"marketSubscription"@
  | E'OpTypes'OrderSubscription -- ^ @"orderSubscription"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'OpTypes where toJSON = A.toJSON . fromE'OpTypes
instance A.FromJSON E'OpTypes where parseJSON o = P.either P.fail (pure . P.id) . toE'OpTypes =<< A.parseJSON o

-- | unwrap 'E'OpTypes' enum
fromE'OpTypes :: E'OpTypes -> Text
fromE'OpTypes = \case
  E'OpTypes'Heartbeat -> "heartbeat"
  E'OpTypes'Authentication -> "authentication"
  E'OpTypes'MarketSubscription -> "marketSubscription"
  E'OpTypes'OrderSubscription -> "orderSubscription"

-- | parse 'E'OpTypes' enum
toE'OpTypes :: Text -> P.Either String E'OpTypes
toE'OpTypes = \case
  "heartbeat" -> P.Right E'OpTypes'Heartbeat
  "authentication" -> P.Right E'OpTypes'Authentication
  "marketSubscription" -> P.Right E'OpTypes'MarketSubscription
  "orderSubscription" -> P.Right E'OpTypes'OrderSubscription
  s -> P.Left $ "toE'OpTypes: enum parse failure: " P.++ P.show s


-- ** E'OpTypes2

-- | Enum of 'Text'
data E'OpTypes2
  = E'OpTypes2'Connection -- ^ @"connection"@
  | E'OpTypes2'Status -- ^ @"status"@
  | E'OpTypes2'Mcm -- ^ @"mcm"@
  | E'OpTypes2'Ocm -- ^ @"ocm"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'OpTypes2 where toJSON = A.toJSON . fromE'OpTypes2
instance A.FromJSON E'OpTypes2 where parseJSON o = P.either P.fail (pure . P.id) . toE'OpTypes2 =<< A.parseJSON o

-- | unwrap 'E'OpTypes2' enum
fromE'OpTypes2 :: E'OpTypes2 -> Text
fromE'OpTypes2 = \case
  E'OpTypes2'Connection -> "connection"
  E'OpTypes2'Status -> "status"
  E'OpTypes2'Mcm -> "mcm"
  E'OpTypes2'Ocm -> "ocm"

-- | parse 'E'OpTypes2' enum
toE'OpTypes2 :: Text -> P.Either String E'OpTypes2
toE'OpTypes2 = \case
  "connection" -> P.Right E'OpTypes2'Connection
  "status" -> P.Right E'OpTypes2'Status
  "mcm" -> P.Right E'OpTypes2'Mcm
  "ocm" -> P.Right E'OpTypes2'Ocm
  s -> P.Left $ "toE'OpTypes2: enum parse failure: " P.++ P.show s


-- ** E'Ot

-- | Enum of 'Text' .
-- Order Type - the type of the order (L = LIMIT, MOC = MARKET_ON_CLOSE, LOC = LIMIT_ON_CLOSE)
data E'Ot
  = E'Ot'L -- ^ @"L"@
  | E'Ot'LOC -- ^ @"LOC"@
  | E'Ot'MOC -- ^ @"MOC"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'Ot where toJSON = A.toJSON . fromE'Ot
instance A.FromJSON E'Ot where parseJSON o = P.either P.fail (pure . P.id) . toE'Ot =<< A.parseJSON o

-- | unwrap 'E'Ot' enum
fromE'Ot :: E'Ot -> Text
fromE'Ot = \case
  E'Ot'L -> "L"
  E'Ot'LOC -> "LOC"
  E'Ot'MOC -> "MOC"

-- | parse 'E'Ot' enum
toE'Ot :: Text -> P.Either String E'Ot
toE'Ot = \case
  "L" -> P.Right E'Ot'L
  "LOC" -> P.Right E'Ot'LOC
  "MOC" -> P.Right E'Ot'MOC
  s -> P.Left $ "toE'Ot: enum parse failure: " P.++ P.show s


-- ** E'Pt

-- | Enum of 'Text' .
-- Persistence Type - whether the order will persist at in play or not (L = LAPSE, P = PERSIST, MOC = Market On Close)
data E'Pt
  = E'Pt'L -- ^ @"L"@
  | E'Pt'P -- ^ @"P"@
  | E'Pt'MOC -- ^ @"MOC"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'Pt where toJSON = A.toJSON . fromE'Pt
instance A.FromJSON E'Pt where parseJSON o = P.either P.fail (pure . P.id) . toE'Pt =<< A.parseJSON o

-- | unwrap 'E'Pt' enum
fromE'Pt :: E'Pt -> Text
fromE'Pt = \case
  E'Pt'L -> "L"
  E'Pt'P -> "P"
  E'Pt'MOC -> "MOC"

-- | parse 'E'Pt' enum
toE'Pt :: Text -> P.Either String E'Pt
toE'Pt = \case
  "L" -> P.Right E'Pt'L
  "P" -> P.Right E'Pt'P
  "MOC" -> P.Right E'Pt'MOC
  s -> P.Left $ "toE'Pt: enum parse failure: " P.++ P.show s


-- ** E'SegmentType

-- | Enum of 'Text' .
-- Segment Type - if the change is split into multiple segments, this denotes the beginning and end of a change, and segments in between. Will be null if data is not segmented
data E'SegmentType
  = E'SegmentType'SEG_START -- ^ @"SEG_START"@
  | E'SegmentType'SEG -- ^ @"SEG"@
  | E'SegmentType'SEG_END -- ^ @"SEG_END"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'SegmentType where toJSON = A.toJSON . fromE'SegmentType
instance A.FromJSON E'SegmentType where parseJSON o = P.either P.fail (pure . P.id) . toE'SegmentType =<< A.parseJSON o

-- | unwrap 'E'SegmentType' enum
fromE'SegmentType :: E'SegmentType -> Text
fromE'SegmentType = \case
  E'SegmentType'SEG_START -> "SEG_START"
  E'SegmentType'SEG -> "SEG"
  E'SegmentType'SEG_END -> "SEG_END"

-- | parse 'E'SegmentType' enum
toE'SegmentType :: Text -> P.Either String E'SegmentType
toE'SegmentType = \case
  "SEG_START" -> P.Right E'SegmentType'SEG_START
  "SEG" -> P.Right E'SegmentType'SEG
  "SEG_END" -> P.Right E'SegmentType'SEG_END
  s -> P.Left $ "toE'SegmentType: enum parse failure: " P.++ P.show s


-- ** E'Side

-- | Enum of 'Text' .
-- Side - the side of the order. For Line markets a 'B' bet refers to a SELL line and an 'L' bet refers to a BUY line.
data E'Side
  = E'Side'B -- ^ @"B"@
  | E'Side'L -- ^ @"L"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'Side where toJSON = A.toJSON . fromE'Side
instance A.FromJSON E'Side where parseJSON o = P.either P.fail (pure . P.id) . toE'Side =<< A.parseJSON o

-- | unwrap 'E'Side' enum
fromE'Side :: E'Side -> Text
fromE'Side = \case
  E'Side'B -> "B"
  E'Side'L -> "L"

-- | parse 'E'Side' enum
toE'Side :: Text -> P.Either String E'Side
toE'Side = \case
  "B" -> P.Right E'Side'B
  "L" -> P.Right E'Side'L
  s -> P.Left $ "toE'Side: enum parse failure: " P.++ P.show s


-- ** E'Status

-- | Enum of 'Text'
data E'Status
  = E'Status'INACTIVE -- ^ @"INACTIVE"@
  | E'Status'OPEN -- ^ @"OPEN"@
  | E'Status'SUSPENDED -- ^ @"SUSPENDED"@
  | E'Status'CLOSED -- ^ @"CLOSED"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'Status where toJSON = A.toJSON . fromE'Status
instance A.FromJSON E'Status where parseJSON o = P.either P.fail (pure . P.id) . toE'Status =<< A.parseJSON o

-- | unwrap 'E'Status' enum
fromE'Status :: E'Status -> Text
fromE'Status = \case
  E'Status'INACTIVE -> "INACTIVE"
  E'Status'OPEN -> "OPEN"
  E'Status'SUSPENDED -> "SUSPENDED"
  E'Status'CLOSED -> "CLOSED"

-- | parse 'E'Status' enum
toE'Status :: Text -> P.Either String E'Status
toE'Status = \case
  "INACTIVE" -> P.Right E'Status'INACTIVE
  "OPEN" -> P.Right E'Status'OPEN
  "SUSPENDED" -> P.Right E'Status'SUSPENDED
  "CLOSED" -> P.Right E'Status'CLOSED
  s -> P.Left $ "toE'Status: enum parse failure: " P.++ P.show s


-- ** E'Status2

-- | Enum of 'Text'
data E'Status2
  = E'Status2'ACTIVE -- ^ @"ACTIVE"@
  | E'Status2'WINNER -- ^ @"WINNER"@
  | E'Status2'LOSER -- ^ @"LOSER"@
  | E'Status2'REMOVED -- ^ @"REMOVED"@
  | E'Status2'REMOVED_VACANT -- ^ @"REMOVED_VACANT"@
  | E'Status2'HIDDEN -- ^ @"HIDDEN"@
  | E'Status2'PLACED -- ^ @"PLACED"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'Status2 where toJSON = A.toJSON . fromE'Status2
instance A.FromJSON E'Status2 where parseJSON o = P.either P.fail (pure . P.id) . toE'Status2 =<< A.parseJSON o

-- | unwrap 'E'Status2' enum
fromE'Status2 :: E'Status2 -> Text
fromE'Status2 = \case
  E'Status2'ACTIVE -> "ACTIVE"
  E'Status2'WINNER -> "WINNER"
  E'Status2'LOSER -> "LOSER"
  E'Status2'REMOVED -> "REMOVED"
  E'Status2'REMOVED_VACANT -> "REMOVED_VACANT"
  E'Status2'HIDDEN -> "HIDDEN"
  E'Status2'PLACED -> "PLACED"

-- | parse 'E'Status2' enum
toE'Status2 :: Text -> P.Either String E'Status2
toE'Status2 = \case
  "ACTIVE" -> P.Right E'Status2'ACTIVE
  "WINNER" -> P.Right E'Status2'WINNER
  "LOSER" -> P.Right E'Status2'LOSER
  "REMOVED" -> P.Right E'Status2'REMOVED
  "REMOVED_VACANT" -> P.Right E'Status2'REMOVED_VACANT
  "HIDDEN" -> P.Right E'Status2'HIDDEN
  "PLACED" -> P.Right E'Status2'PLACED
  s -> P.Left $ "toE'Status2: enum parse failure: " P.++ P.show s


-- ** E'Status3

-- | Enum of 'Text' .
-- Status - the status of the order (E = EXECUTABLE, EC = EXECUTION_COMPLETE)
data E'Status3
  = E'Status3'E -- ^ @"E"@
  | E'Status3'EC -- ^ @"EC"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'Status3 where toJSON = A.toJSON . fromE'Status3
instance A.FromJSON E'Status3 where parseJSON o = P.either P.fail (pure . P.id) . toE'Status3 =<< A.parseJSON o

-- | unwrap 'E'Status3' enum
fromE'Status3 :: E'Status3 -> Text
fromE'Status3 = \case
  E'Status3'E -> "E"
  E'Status3'EC -> "EC"

-- | parse 'E'Status3' enum
toE'Status3 :: Text -> P.Either String E'Status3
toE'Status3 = \case
  "E" -> P.Right E'Status3'E
  "EC" -> P.Right E'Status3'EC
  s -> P.Left $ "toE'Status3: enum parse failure: " P.++ P.show s


-- ** E'StatusCode

-- | Enum of 'Text' .
-- The status of the last request
data E'StatusCode
  = E'StatusCode'SUCCESS -- ^ @"SUCCESS"@
  | E'StatusCode'FAILURE -- ^ @"FAILURE"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'StatusCode where toJSON = A.toJSON . fromE'StatusCode
instance A.FromJSON E'StatusCode where parseJSON o = P.either P.fail (pure . P.id) . toE'StatusCode =<< A.parseJSON o

-- | unwrap 'E'StatusCode' enum
fromE'StatusCode :: E'StatusCode -> Text
fromE'StatusCode = \case
  E'StatusCode'SUCCESS -> "SUCCESS"
  E'StatusCode'FAILURE -> "FAILURE"

-- | parse 'E'StatusCode' enum
toE'StatusCode :: Text -> P.Either String E'StatusCode
toE'StatusCode = \case
  "SUCCESS" -> P.Right E'StatusCode'SUCCESS
  "FAILURE" -> P.Right E'StatusCode'FAILURE
  s -> P.Left $ "toE'StatusCode: enum parse failure: " P.++ P.show s


-- ** E'Type

-- | Enum of 'Text'
data E'Type
  = E'Type'CLASSIC -- ^ @"CLASSIC"@
  | E'Type'FINEST -- ^ @"FINEST"@
  | E'Type'LINE_RANGE -- ^ @"LINE_RANGE"@
  deriving (P.Show, P.Eq, P.Typeable, P.Ord, P.Bounded, P.Enum)

instance A.ToJSON E'Type where toJSON = A.toJSON . fromE'Type
instance A.FromJSON E'Type where parseJSON o = P.either P.fail (pure . P.id) . toE'Type =<< A.parseJSON o

-- | unwrap 'E'Type' enum
fromE'Type :: E'Type -> Text
fromE'Type = \case
  E'Type'CLASSIC -> "CLASSIC"
  E'Type'FINEST -> "FINEST"
  E'Type'LINE_RANGE -> "LINE_RANGE"

-- | parse 'E'Type' enum
toE'Type :: Text -> P.Either String E'Type
toE'Type = \case
  "CLASSIC" -> P.Right E'Type'CLASSIC
  "FINEST" -> P.Right E'Type'FINEST
  "LINE_RANGE" -> P.Right E'Type'LINE_RANGE
  s -> P.Left $ "toE'Type: enum parse failure: " P.++ P.show s