{-# LANGUAGE CPP                        #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase                 #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE PatternSynonyms            #-}
{-# LANGUAGE RecordWildCards            #-}
{-# LANGUAGE ScopedTypeVariables        #-}
{-# LANGUAGE TypeInType                 #-}
{-# LANGUAGE TypeOperators              #-}
{-# LANGUAGE ViewPatterns               #-}

-- |
-- Module      : Advent.Types
-- Copyright   : (c) Justin Le 2019
-- License     : BSD3
--
-- Maintainer  : justin@jle.im
-- Stability   : experimental
-- Portability : non-portable
--
-- Data types used for the underlying API.
--
-- @since 0.2.3.0
--

module Advent.Types (
  -- * Types
    Day(..)
  , Part(..)
  , SubmitInfo(..)
  , SubmitRes(..), showSubmitRes
  , PublicCode(..)
  , Leaderboard(..)
  , LeaderboardMember(..)
  , Rank(..)
  , DailyLeaderboard(..)
  , DailyLeaderboardMember(..)
  , GlobalLeaderboard(..)
  , GlobalLeaderboardMember(..)
  , NextDayTime(..)
  -- * Util
  , mkDay, mkDay_, dayInt
  , _DayInt, pattern DayInt
  , partInt
  , partChar
  , fullDailyBoard
  , dlbmCompleteTime
  , dlbmTime
  , challengeReleaseTime
  -- * Internal
  , parseSubmitRes
  ) where

import           Control.Applicative
import           Data.Aeson
import           Data.Aeson.Types
import           Data.Bifunctor
import           Data.Char
import           Data.Finite
import           Data.Foldable
import           Data.Functor.Classes
import           Data.List.NonEmpty         (NonEmpty(..))
import           Data.Map                   (Map)
import           Data.Maybe
import           Data.Profunctor
import           Data.Text                  (Text)
import           Data.Time hiding           (Day)
import           Data.Time.Clock.POSIX
import           Data.Typeable
import           Data.Void
import           GHC.Generics
import           Servant.API
import           Text.Printf
import           Text.Read                  (readMaybe)
import qualified Data.Map                   as M
import qualified Data.Text                  as T
import qualified Text.HTML.TagSoup          as H
import qualified Text.Megaparsec            as P
import qualified Text.Megaparsec.Char       as P
import qualified Text.Megaparsec.Char.Lexer as P
import qualified Web.FormUrlEncoded         as WF

#if !MIN_VERSION_base(4,11,0)
import           Data.Semigroup ((<>))
#endif

#if !MIN_VERSION_time(1,9,0)
import           Data.Time.LocalTime.Compat
#endif

-- | Describes the day: a number between 1 and 25 inclusive.
--
-- Represented by a 'Finite' ranging from 0 to 24 inclusive; you should
-- probably make one using the smart constructor 'mkDay'.
newtype Day = Day { Day -> Finite 25
dayFinite :: Finite 25 }
  deriving (Day -> Day -> Bool
(Day -> Day -> Bool) -> (Day -> Day -> Bool) -> Eq Day
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Day -> Day -> Bool
$c/= :: Day -> Day -> Bool
== :: Day -> Day -> Bool
$c== :: Day -> Day -> Bool
Eq, Eq Day
Eq Day
-> (Day -> Day -> Ordering)
-> (Day -> Day -> Bool)
-> (Day -> Day -> Bool)
-> (Day -> Day -> Bool)
-> (Day -> Day -> Bool)
-> (Day -> Day -> Day)
-> (Day -> Day -> Day)
-> Ord Day
Day -> Day -> Bool
Day -> Day -> Ordering
Day -> Day -> Day
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Day -> Day -> Day
$cmin :: Day -> Day -> Day
max :: Day -> Day -> Day
$cmax :: Day -> Day -> Day
>= :: Day -> Day -> Bool
$c>= :: Day -> Day -> Bool
> :: Day -> Day -> Bool
$c> :: Day -> Day -> Bool
<= :: Day -> Day -> Bool
$c<= :: Day -> Day -> Bool
< :: Day -> Day -> Bool
$c< :: Day -> Day -> Bool
compare :: Day -> Day -> Ordering
$ccompare :: Day -> Day -> Ordering
$cp1Ord :: Eq Day
Ord, Int -> Day
Day -> Int
Day -> [Day]
Day -> Day
Day -> Day -> [Day]
Day -> Day -> Day -> [Day]
(Day -> Day)
-> (Day -> Day)
-> (Int -> Day)
-> (Day -> Int)
-> (Day -> [Day])
-> (Day -> Day -> [Day])
-> (Day -> Day -> [Day])
-> (Day -> Day -> Day -> [Day])
-> Enum Day
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Day -> Day -> Day -> [Day]
$cenumFromThenTo :: Day -> Day -> Day -> [Day]
enumFromTo :: Day -> Day -> [Day]
$cenumFromTo :: Day -> Day -> [Day]
enumFromThen :: Day -> Day -> [Day]
$cenumFromThen :: Day -> Day -> [Day]
enumFrom :: Day -> [Day]
$cenumFrom :: Day -> [Day]
fromEnum :: Day -> Int
$cfromEnum :: Day -> Int
toEnum :: Int -> Day
$ctoEnum :: Int -> Day
pred :: Day -> Day
$cpred :: Day -> Day
succ :: Day -> Day
$csucc :: Day -> Day
Enum, Day
Day -> Day -> Bounded Day
forall a. a -> a -> Bounded a
maxBound :: Day
$cmaxBound :: Day
minBound :: Day
$cminBound :: Day
Bounded, Typeable, (forall x. Day -> Rep Day x)
-> (forall x. Rep Day x -> Day) -> Generic Day
forall x. Rep Day x -> Day
forall x. Day -> Rep Day x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Day x -> Day
$cfrom :: forall x. Day -> Rep Day x
Generic)

instance Show Day where
    showsPrec :: Int -> Day -> ShowS
showsPrec = (Int -> Day -> ShowS) -> String -> Int -> Day -> ShowS
forall a. (Int -> a -> ShowS) -> String -> Int -> a -> ShowS
showsUnaryWith (\Int
d -> Int -> Integer -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
d (Integer -> ShowS) -> (Day -> Integer) -> Day -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Integer
dayInt) String
"mkDay"

-- | A given part of a problem.  All Advent of Code challenges are
-- two-parts.
--
-- You can usually get 'Part1' (if it is already released) with a nonsense
-- session key, but 'Part2' always requires a valid session key.
data Part = Part1 | Part2
  deriving (Int -> Part -> ShowS
[Part] -> ShowS
Part -> String
(Int -> Part -> ShowS)
-> (Part -> String) -> ([Part] -> ShowS) -> Show Part
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Part] -> ShowS
$cshowList :: [Part] -> ShowS
show :: Part -> String
$cshow :: Part -> String
showsPrec :: Int -> Part -> ShowS
$cshowsPrec :: Int -> Part -> ShowS
Show, ReadPrec [Part]
ReadPrec Part
Int -> ReadS Part
ReadS [Part]
(Int -> ReadS Part)
-> ReadS [Part] -> ReadPrec Part -> ReadPrec [Part] -> Read Part
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Part]
$creadListPrec :: ReadPrec [Part]
readPrec :: ReadPrec Part
$creadPrec :: ReadPrec Part
readList :: ReadS [Part]
$creadList :: ReadS [Part]
readsPrec :: Int -> ReadS Part
$creadsPrec :: Int -> ReadS Part
Read, Part -> Part -> Bool
(Part -> Part -> Bool) -> (Part -> Part -> Bool) -> Eq Part
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Part -> Part -> Bool
$c/= :: Part -> Part -> Bool
== :: Part -> Part -> Bool
$c== :: Part -> Part -> Bool
Eq, Eq Part
Eq Part
-> (Part -> Part -> Ordering)
-> (Part -> Part -> Bool)
-> (Part -> Part -> Bool)
-> (Part -> Part -> Bool)
-> (Part -> Part -> Bool)
-> (Part -> Part -> Part)
-> (Part -> Part -> Part)
-> Ord Part
Part -> Part -> Bool
Part -> Part -> Ordering
Part -> Part -> Part
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Part -> Part -> Part
$cmin :: Part -> Part -> Part
max :: Part -> Part -> Part
$cmax :: Part -> Part -> Part
>= :: Part -> Part -> Bool
$c>= :: Part -> Part -> Bool
> :: Part -> Part -> Bool
$c> :: Part -> Part -> Bool
<= :: Part -> Part -> Bool
$c<= :: Part -> Part -> Bool
< :: Part -> Part -> Bool
$c< :: Part -> Part -> Bool
compare :: Part -> Part -> Ordering
$ccompare :: Part -> Part -> Ordering
$cp1Ord :: Eq Part
Ord, Int -> Part
Part -> Int
Part -> [Part]
Part -> Part
Part -> Part -> [Part]
Part -> Part -> Part -> [Part]
(Part -> Part)
-> (Part -> Part)
-> (Int -> Part)
-> (Part -> Int)
-> (Part -> [Part])
-> (Part -> Part -> [Part])
-> (Part -> Part -> [Part])
-> (Part -> Part -> Part -> [Part])
-> Enum Part
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Part -> Part -> Part -> [Part]
$cenumFromThenTo :: Part -> Part -> Part -> [Part]
enumFromTo :: Part -> Part -> [Part]
$cenumFromTo :: Part -> Part -> [Part]
enumFromThen :: Part -> Part -> [Part]
$cenumFromThen :: Part -> Part -> [Part]
enumFrom :: Part -> [Part]
$cenumFrom :: Part -> [Part]
fromEnum :: Part -> Int
$cfromEnum :: Part -> Int
toEnum :: Int -> Part
$ctoEnum :: Int -> Part
pred :: Part -> Part
$cpred :: Part -> Part
succ :: Part -> Part
$csucc :: Part -> Part
Enum, Part
Part -> Part -> Bounded Part
forall a. a -> a -> Bounded a
maxBound :: Part
$cmaxBound :: Part
minBound :: Part
$cminBound :: Part
Bounded, Typeable, (forall x. Part -> Rep Part x)
-> (forall x. Rep Part x -> Part) -> Generic Part
forall x. Rep Part x -> Part
forall x. Part -> Rep Part x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Part x -> Part
$cfrom :: forall x. Part -> Rep Part x
Generic)

-- | Info required to submit an answer for a part.
data SubmitInfo = SubmitInfo
    { SubmitInfo -> Part
siLevel  :: Part
    , SubmitInfo -> String
siAnswer :: String
    }
  deriving (Int -> SubmitInfo -> ShowS
[SubmitInfo] -> ShowS
SubmitInfo -> String
(Int -> SubmitInfo -> ShowS)
-> (SubmitInfo -> String)
-> ([SubmitInfo] -> ShowS)
-> Show SubmitInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SubmitInfo] -> ShowS
$cshowList :: [SubmitInfo] -> ShowS
show :: SubmitInfo -> String
$cshow :: SubmitInfo -> String
showsPrec :: Int -> SubmitInfo -> ShowS
$cshowsPrec :: Int -> SubmitInfo -> ShowS
Show, ReadPrec [SubmitInfo]
ReadPrec SubmitInfo
Int -> ReadS SubmitInfo
ReadS [SubmitInfo]
(Int -> ReadS SubmitInfo)
-> ReadS [SubmitInfo]
-> ReadPrec SubmitInfo
-> ReadPrec [SubmitInfo]
-> Read SubmitInfo
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SubmitInfo]
$creadListPrec :: ReadPrec [SubmitInfo]
readPrec :: ReadPrec SubmitInfo
$creadPrec :: ReadPrec SubmitInfo
readList :: ReadS [SubmitInfo]
$creadList :: ReadS [SubmitInfo]
readsPrec :: Int -> ReadS SubmitInfo
$creadsPrec :: Int -> ReadS SubmitInfo
Read, SubmitInfo -> SubmitInfo -> Bool
(SubmitInfo -> SubmitInfo -> Bool)
-> (SubmitInfo -> SubmitInfo -> Bool) -> Eq SubmitInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SubmitInfo -> SubmitInfo -> Bool
$c/= :: SubmitInfo -> SubmitInfo -> Bool
== :: SubmitInfo -> SubmitInfo -> Bool
$c== :: SubmitInfo -> SubmitInfo -> Bool
Eq, Eq SubmitInfo
Eq SubmitInfo
-> (SubmitInfo -> SubmitInfo -> Ordering)
-> (SubmitInfo -> SubmitInfo -> Bool)
-> (SubmitInfo -> SubmitInfo -> Bool)
-> (SubmitInfo -> SubmitInfo -> Bool)
-> (SubmitInfo -> SubmitInfo -> Bool)
-> (SubmitInfo -> SubmitInfo -> SubmitInfo)
-> (SubmitInfo -> SubmitInfo -> SubmitInfo)
-> Ord SubmitInfo
SubmitInfo -> SubmitInfo -> Bool
SubmitInfo -> SubmitInfo -> Ordering
SubmitInfo -> SubmitInfo -> SubmitInfo
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SubmitInfo -> SubmitInfo -> SubmitInfo
$cmin :: SubmitInfo -> SubmitInfo -> SubmitInfo
max :: SubmitInfo -> SubmitInfo -> SubmitInfo
$cmax :: SubmitInfo -> SubmitInfo -> SubmitInfo
>= :: SubmitInfo -> SubmitInfo -> Bool
$c>= :: SubmitInfo -> SubmitInfo -> Bool
> :: SubmitInfo -> SubmitInfo -> Bool
$c> :: SubmitInfo -> SubmitInfo -> Bool
<= :: SubmitInfo -> SubmitInfo -> Bool
$c<= :: SubmitInfo -> SubmitInfo -> Bool
< :: SubmitInfo -> SubmitInfo -> Bool
$c< :: SubmitInfo -> SubmitInfo -> Bool
compare :: SubmitInfo -> SubmitInfo -> Ordering
$ccompare :: SubmitInfo -> SubmitInfo -> Ordering
$cp1Ord :: Eq SubmitInfo
Ord, Typeable, (forall x. SubmitInfo -> Rep SubmitInfo x)
-> (forall x. Rep SubmitInfo x -> SubmitInfo) -> Generic SubmitInfo
forall x. Rep SubmitInfo x -> SubmitInfo
forall x. SubmitInfo -> Rep SubmitInfo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SubmitInfo x -> SubmitInfo
$cfrom :: forall x. SubmitInfo -> Rep SubmitInfo x
Generic)

-- | The result of a submission.
data SubmitRes
    -- | Correct submission, including global rank (if reported, which
    -- usually happens if rank is under 1000)
    = SubCorrect (Maybe Integer)
    -- | Incorrect submission.  Contains the number of /seconds/ you must
    -- wait before trying again.  The 'Maybe' contains possible hints given
    -- by the server (usually "too low" or "too high").
    | SubIncorrect Int (Maybe String)
    -- | Submission was rejected because an incorrect submission was
    -- recently submitted.  Contains the number of /seconds/ you must wait
    -- before trying again.
    | SubWait Int
    -- | Submission was rejected because it was sent to an invalid question
    -- or part.  Usually happens if you submit to a part you have already
    -- answered or have not yet unlocked.
    | SubInvalid
    -- | Could not parse server response.  Contains parse error.
    | SubUnknown String
  deriving (Int -> SubmitRes -> ShowS
[SubmitRes] -> ShowS
SubmitRes -> String
(Int -> SubmitRes -> ShowS)
-> (SubmitRes -> String)
-> ([SubmitRes] -> ShowS)
-> Show SubmitRes
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SubmitRes] -> ShowS
$cshowList :: [SubmitRes] -> ShowS
show :: SubmitRes -> String
$cshow :: SubmitRes -> String
showsPrec :: Int -> SubmitRes -> ShowS
$cshowsPrec :: Int -> SubmitRes -> ShowS
Show, ReadPrec [SubmitRes]
ReadPrec SubmitRes
Int -> ReadS SubmitRes
ReadS [SubmitRes]
(Int -> ReadS SubmitRes)
-> ReadS [SubmitRes]
-> ReadPrec SubmitRes
-> ReadPrec [SubmitRes]
-> Read SubmitRes
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SubmitRes]
$creadListPrec :: ReadPrec [SubmitRes]
readPrec :: ReadPrec SubmitRes
$creadPrec :: ReadPrec SubmitRes
readList :: ReadS [SubmitRes]
$creadList :: ReadS [SubmitRes]
readsPrec :: Int -> ReadS SubmitRes
$creadsPrec :: Int -> ReadS SubmitRes
Read, SubmitRes -> SubmitRes -> Bool
(SubmitRes -> SubmitRes -> Bool)
-> (SubmitRes -> SubmitRes -> Bool) -> Eq SubmitRes
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SubmitRes -> SubmitRes -> Bool
$c/= :: SubmitRes -> SubmitRes -> Bool
== :: SubmitRes -> SubmitRes -> Bool
$c== :: SubmitRes -> SubmitRes -> Bool
Eq, Eq SubmitRes
Eq SubmitRes
-> (SubmitRes -> SubmitRes -> Ordering)
-> (SubmitRes -> SubmitRes -> Bool)
-> (SubmitRes -> SubmitRes -> Bool)
-> (SubmitRes -> SubmitRes -> Bool)
-> (SubmitRes -> SubmitRes -> Bool)
-> (SubmitRes -> SubmitRes -> SubmitRes)
-> (SubmitRes -> SubmitRes -> SubmitRes)
-> Ord SubmitRes
SubmitRes -> SubmitRes -> Bool
SubmitRes -> SubmitRes -> Ordering
SubmitRes -> SubmitRes -> SubmitRes
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SubmitRes -> SubmitRes -> SubmitRes
$cmin :: SubmitRes -> SubmitRes -> SubmitRes
max :: SubmitRes -> SubmitRes -> SubmitRes
$cmax :: SubmitRes -> SubmitRes -> SubmitRes
>= :: SubmitRes -> SubmitRes -> Bool
$c>= :: SubmitRes -> SubmitRes -> Bool
> :: SubmitRes -> SubmitRes -> Bool
$c> :: SubmitRes -> SubmitRes -> Bool
<= :: SubmitRes -> SubmitRes -> Bool
$c<= :: SubmitRes -> SubmitRes -> Bool
< :: SubmitRes -> SubmitRes -> Bool
$c< :: SubmitRes -> SubmitRes -> Bool
compare :: SubmitRes -> SubmitRes -> Ordering
$ccompare :: SubmitRes -> SubmitRes -> Ordering
$cp1Ord :: Eq SubmitRes
Ord, Typeable, (forall x. SubmitRes -> Rep SubmitRes x)
-> (forall x. Rep SubmitRes x -> SubmitRes) -> Generic SubmitRes
forall x. Rep SubmitRes x -> SubmitRes
forall x. SubmitRes -> Rep SubmitRes x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SubmitRes x -> SubmitRes
$cfrom :: forall x. SubmitRes -> Rep SubmitRes x
Generic)

-- | Member ID of public leaderboard (the first part of the registration
-- code, before the hyphen).  It can be found as the number in the URL:
--
-- > https://adventofcode.com/2019/leaderboard/private/view/12345
--
-- (the @12345@ above)
newtype PublicCode = PublicCode { PublicCode -> Integer
getPublicCode :: Integer }
  deriving (Int -> PublicCode -> ShowS
[PublicCode] -> ShowS
PublicCode -> String
(Int -> PublicCode -> ShowS)
-> (PublicCode -> String)
-> ([PublicCode] -> ShowS)
-> Show PublicCode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PublicCode] -> ShowS
$cshowList :: [PublicCode] -> ShowS
show :: PublicCode -> String
$cshow :: PublicCode -> String
showsPrec :: Int -> PublicCode -> ShowS
$cshowsPrec :: Int -> PublicCode -> ShowS
Show, ReadPrec [PublicCode]
ReadPrec PublicCode
Int -> ReadS PublicCode
ReadS [PublicCode]
(Int -> ReadS PublicCode)
-> ReadS [PublicCode]
-> ReadPrec PublicCode
-> ReadPrec [PublicCode]
-> Read PublicCode
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PublicCode]
$creadListPrec :: ReadPrec [PublicCode]
readPrec :: ReadPrec PublicCode
$creadPrec :: ReadPrec PublicCode
readList :: ReadS [PublicCode]
$creadList :: ReadS [PublicCode]
readsPrec :: Int -> ReadS PublicCode
$creadsPrec :: Int -> ReadS PublicCode
Read, PublicCode -> PublicCode -> Bool
(PublicCode -> PublicCode -> Bool)
-> (PublicCode -> PublicCode -> Bool) -> Eq PublicCode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PublicCode -> PublicCode -> Bool
$c/= :: PublicCode -> PublicCode -> Bool
== :: PublicCode -> PublicCode -> Bool
$c== :: PublicCode -> PublicCode -> Bool
Eq, Eq PublicCode
Eq PublicCode
-> (PublicCode -> PublicCode -> Ordering)
-> (PublicCode -> PublicCode -> Bool)
-> (PublicCode -> PublicCode -> Bool)
-> (PublicCode -> PublicCode -> Bool)
-> (PublicCode -> PublicCode -> Bool)
-> (PublicCode -> PublicCode -> PublicCode)
-> (PublicCode -> PublicCode -> PublicCode)
-> Ord PublicCode
PublicCode -> PublicCode -> Bool
PublicCode -> PublicCode -> Ordering
PublicCode -> PublicCode -> PublicCode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PublicCode -> PublicCode -> PublicCode
$cmin :: PublicCode -> PublicCode -> PublicCode
max :: PublicCode -> PublicCode -> PublicCode
$cmax :: PublicCode -> PublicCode -> PublicCode
>= :: PublicCode -> PublicCode -> Bool
$c>= :: PublicCode -> PublicCode -> Bool
> :: PublicCode -> PublicCode -> Bool
$c> :: PublicCode -> PublicCode -> Bool
<= :: PublicCode -> PublicCode -> Bool
$c<= :: PublicCode -> PublicCode -> Bool
< :: PublicCode -> PublicCode -> Bool
$c< :: PublicCode -> PublicCode -> Bool
compare :: PublicCode -> PublicCode -> Ordering
$ccompare :: PublicCode -> PublicCode -> Ordering
$cp1Ord :: Eq PublicCode
Ord, Typeable, (forall x. PublicCode -> Rep PublicCode x)
-> (forall x. Rep PublicCode x -> PublicCode) -> Generic PublicCode
forall x. Rep PublicCode x -> PublicCode
forall x. PublicCode -> Rep PublicCode x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PublicCode x -> PublicCode
$cfrom :: forall x. PublicCode -> Rep PublicCode x
Generic)

-- | Leaderboard type, representing private leaderboard information.
data Leaderboard = LB
    { Leaderboard -> Integer
lbEvent   :: Integer                        -- ^ The year of the event
    , Leaderboard -> Integer
lbOwnerId :: Integer                        -- ^ The Member ID of the owner, or the public code
    , Leaderboard -> Map Integer LeaderboardMember
lbMembers :: Map Integer LeaderboardMember  -- ^ A map from member IDs to their leaderboard info
    }
  deriving (Int -> Leaderboard -> ShowS
[Leaderboard] -> ShowS
Leaderboard -> String
(Int -> Leaderboard -> ShowS)
-> (Leaderboard -> String)
-> ([Leaderboard] -> ShowS)
-> Show Leaderboard
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Leaderboard] -> ShowS
$cshowList :: [Leaderboard] -> ShowS
show :: Leaderboard -> String
$cshow :: Leaderboard -> String
showsPrec :: Int -> Leaderboard -> ShowS
$cshowsPrec :: Int -> Leaderboard -> ShowS
Show, Leaderboard -> Leaderboard -> Bool
(Leaderboard -> Leaderboard -> Bool)
-> (Leaderboard -> Leaderboard -> Bool) -> Eq Leaderboard
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Leaderboard -> Leaderboard -> Bool
$c/= :: Leaderboard -> Leaderboard -> Bool
== :: Leaderboard -> Leaderboard -> Bool
$c== :: Leaderboard -> Leaderboard -> Bool
Eq, Eq Leaderboard
Eq Leaderboard
-> (Leaderboard -> Leaderboard -> Ordering)
-> (Leaderboard -> Leaderboard -> Bool)
-> (Leaderboard -> Leaderboard -> Bool)
-> (Leaderboard -> Leaderboard -> Bool)
-> (Leaderboard -> Leaderboard -> Bool)
-> (Leaderboard -> Leaderboard -> Leaderboard)
-> (Leaderboard -> Leaderboard -> Leaderboard)
-> Ord Leaderboard
Leaderboard -> Leaderboard -> Bool
Leaderboard -> Leaderboard -> Ordering
Leaderboard -> Leaderboard -> Leaderboard
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Leaderboard -> Leaderboard -> Leaderboard
$cmin :: Leaderboard -> Leaderboard -> Leaderboard
max :: Leaderboard -> Leaderboard -> Leaderboard
$cmax :: Leaderboard -> Leaderboard -> Leaderboard
>= :: Leaderboard -> Leaderboard -> Bool
$c>= :: Leaderboard -> Leaderboard -> Bool
> :: Leaderboard -> Leaderboard -> Bool
$c> :: Leaderboard -> Leaderboard -> Bool
<= :: Leaderboard -> Leaderboard -> Bool
$c<= :: Leaderboard -> Leaderboard -> Bool
< :: Leaderboard -> Leaderboard -> Bool
$c< :: Leaderboard -> Leaderboard -> Bool
compare :: Leaderboard -> Leaderboard -> Ordering
$ccompare :: Leaderboard -> Leaderboard -> Ordering
$cp1Ord :: Eq Leaderboard
Ord, Typeable, (forall x. Leaderboard -> Rep Leaderboard x)
-> (forall x. Rep Leaderboard x -> Leaderboard)
-> Generic Leaderboard
forall x. Rep Leaderboard x -> Leaderboard
forall x. Leaderboard -> Rep Leaderboard x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Leaderboard x -> Leaderboard
$cfrom :: forall x. Leaderboard -> Rep Leaderboard x
Generic)

-- | Leaderboard position for a given member.
data LeaderboardMember = LBM
    { LeaderboardMember -> Integer
lbmGlobalScore :: Integer                     -- ^ Global leaderboard score
    , LeaderboardMember -> Maybe Text
lbmName        :: Maybe Text                  -- ^ Username, if user specifies one
    , LeaderboardMember -> Integer
lbmLocalScore  :: Integer                     -- ^ Score for this leaderboard
    , LeaderboardMember -> Integer
lbmId          :: Integer                     -- ^ Member ID
    , LeaderboardMember -> Maybe UTCTime
lbmLastStarTS  :: Maybe UTCTime               -- ^ Time of last puzzle solved, if any
    , LeaderboardMember -> Int
lbmStars       :: Int                         -- ^ Number of stars (puzzle parts) solved
    , LeaderboardMember -> Map Day (Map Part UTCTime)
lbmCompletion  :: Map Day (Map Part UTCTime)  -- ^ Completion times of each day and puzzle part
    }
  deriving (Int -> LeaderboardMember -> ShowS
[LeaderboardMember] -> ShowS
LeaderboardMember -> String
(Int -> LeaderboardMember -> ShowS)
-> (LeaderboardMember -> String)
-> ([LeaderboardMember] -> ShowS)
-> Show LeaderboardMember
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LeaderboardMember] -> ShowS
$cshowList :: [LeaderboardMember] -> ShowS
show :: LeaderboardMember -> String
$cshow :: LeaderboardMember -> String
showsPrec :: Int -> LeaderboardMember -> ShowS
$cshowsPrec :: Int -> LeaderboardMember -> ShowS
Show, LeaderboardMember -> LeaderboardMember -> Bool
(LeaderboardMember -> LeaderboardMember -> Bool)
-> (LeaderboardMember -> LeaderboardMember -> Bool)
-> Eq LeaderboardMember
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LeaderboardMember -> LeaderboardMember -> Bool
$c/= :: LeaderboardMember -> LeaderboardMember -> Bool
== :: LeaderboardMember -> LeaderboardMember -> Bool
$c== :: LeaderboardMember -> LeaderboardMember -> Bool
Eq, Eq LeaderboardMember
Eq LeaderboardMember
-> (LeaderboardMember -> LeaderboardMember -> Ordering)
-> (LeaderboardMember -> LeaderboardMember -> Bool)
-> (LeaderboardMember -> LeaderboardMember -> Bool)
-> (LeaderboardMember -> LeaderboardMember -> Bool)
-> (LeaderboardMember -> LeaderboardMember -> Bool)
-> (LeaderboardMember -> LeaderboardMember -> LeaderboardMember)
-> (LeaderboardMember -> LeaderboardMember -> LeaderboardMember)
-> Ord LeaderboardMember
LeaderboardMember -> LeaderboardMember -> Bool
LeaderboardMember -> LeaderboardMember -> Ordering
LeaderboardMember -> LeaderboardMember -> LeaderboardMember
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: LeaderboardMember -> LeaderboardMember -> LeaderboardMember
$cmin :: LeaderboardMember -> LeaderboardMember -> LeaderboardMember
max :: LeaderboardMember -> LeaderboardMember -> LeaderboardMember
$cmax :: LeaderboardMember -> LeaderboardMember -> LeaderboardMember
>= :: LeaderboardMember -> LeaderboardMember -> Bool
$c>= :: LeaderboardMember -> LeaderboardMember -> Bool
> :: LeaderboardMember -> LeaderboardMember -> Bool
$c> :: LeaderboardMember -> LeaderboardMember -> Bool
<= :: LeaderboardMember -> LeaderboardMember -> Bool
$c<= :: LeaderboardMember -> LeaderboardMember -> Bool
< :: LeaderboardMember -> LeaderboardMember -> Bool
$c< :: LeaderboardMember -> LeaderboardMember -> Bool
compare :: LeaderboardMember -> LeaderboardMember -> Ordering
$ccompare :: LeaderboardMember -> LeaderboardMember -> Ordering
$cp1Ord :: Eq LeaderboardMember
Ord, Typeable, (forall x. LeaderboardMember -> Rep LeaderboardMember x)
-> (forall x. Rep LeaderboardMember x -> LeaderboardMember)
-> Generic LeaderboardMember
forall x. Rep LeaderboardMember x -> LeaderboardMember
forall x. LeaderboardMember -> Rep LeaderboardMember x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep LeaderboardMember x -> LeaderboardMember
$cfrom :: forall x. LeaderboardMember -> Rep LeaderboardMember x
Generic)

-- | Ranking between 1 to 100, for daily and global leaderboards
--
-- Note that 'getRank' interanlly stores a number from 0 to 99, so be sure
-- to add or subtract accordingly if you want to display or parse it.
--
-- @since 0.2.3.0
newtype Rank = Rank { Rank -> Finite 100
getRank :: Finite 100 }
  deriving (Int -> Rank -> ShowS
[Rank] -> ShowS
Rank -> String
(Int -> Rank -> ShowS)
-> (Rank -> String) -> ([Rank] -> ShowS) -> Show Rank
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Rank] -> ShowS
$cshowList :: [Rank] -> ShowS
show :: Rank -> String
$cshow :: Rank -> String
showsPrec :: Int -> Rank -> ShowS
$cshowsPrec :: Int -> Rank -> ShowS
Show, Rank -> Rank -> Bool
(Rank -> Rank -> Bool) -> (Rank -> Rank -> Bool) -> Eq Rank
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Rank -> Rank -> Bool
$c/= :: Rank -> Rank -> Bool
== :: Rank -> Rank -> Bool
$c== :: Rank -> Rank -> Bool
Eq, Eq Rank
Eq Rank
-> (Rank -> Rank -> Ordering)
-> (Rank -> Rank -> Bool)
-> (Rank -> Rank -> Bool)
-> (Rank -> Rank -> Bool)
-> (Rank -> Rank -> Bool)
-> (Rank -> Rank -> Rank)
-> (Rank -> Rank -> Rank)
-> Ord Rank
Rank -> Rank -> Bool
Rank -> Rank -> Ordering
Rank -> Rank -> Rank
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Rank -> Rank -> Rank
$cmin :: Rank -> Rank -> Rank
max :: Rank -> Rank -> Rank
$cmax :: Rank -> Rank -> Rank
>= :: Rank -> Rank -> Bool
$c>= :: Rank -> Rank -> Bool
> :: Rank -> Rank -> Bool
$c> :: Rank -> Rank -> Bool
<= :: Rank -> Rank -> Bool
$c<= :: Rank -> Rank -> Bool
< :: Rank -> Rank -> Bool
$c< :: Rank -> Rank -> Bool
compare :: Rank -> Rank -> Ordering
$ccompare :: Rank -> Rank -> Ordering
$cp1Ord :: Eq Rank
Ord, Typeable, (forall x. Rank -> Rep Rank x)
-> (forall x. Rep Rank x -> Rank) -> Generic Rank
forall x. Rep Rank x -> Rank
forall x. Rank -> Rep Rank x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Rank x -> Rank
$cfrom :: forall x. Rank -> Rep Rank x
Generic)

-- | Single daily leaderboard position
--
-- @since 0.2.3.0
data DailyLeaderboardMember = DLBM
    { DailyLeaderboardMember -> Rank
dlbmRank      :: Rank
    -- | Time from midnight EST of December 1st for that event.  Use
    -- 'dlbmCompleteTime' to convert to an actual time for event
    -- completion, and 'dlbmTime' to get the time it took to solve.
    --
    -- @since 0.2.7.0
    , DailyLeaderboardMember -> NominalDiffTime
dlbmDecTime   :: NominalDiffTime      -- ^ time from midnight EST.
    , DailyLeaderboardMember -> Either Integer Text
dlbmUser      :: Either Integer Text
    , DailyLeaderboardMember -> Maybe Text
dlbmLink      :: Maybe Text
    , DailyLeaderboardMember -> Maybe Text
dlbmImage     :: Maybe Text
    , DailyLeaderboardMember -> Bool
dlbmSupporter :: Bool
    }
  deriving (Int -> DailyLeaderboardMember -> ShowS
[DailyLeaderboardMember] -> ShowS
DailyLeaderboardMember -> String
(Int -> DailyLeaderboardMember -> ShowS)
-> (DailyLeaderboardMember -> String)
-> ([DailyLeaderboardMember] -> ShowS)
-> Show DailyLeaderboardMember
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DailyLeaderboardMember] -> ShowS
$cshowList :: [DailyLeaderboardMember] -> ShowS
show :: DailyLeaderboardMember -> String
$cshow :: DailyLeaderboardMember -> String
showsPrec :: Int -> DailyLeaderboardMember -> ShowS
$cshowsPrec :: Int -> DailyLeaderboardMember -> ShowS
Show, DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
(DailyLeaderboardMember -> DailyLeaderboardMember -> Bool)
-> (DailyLeaderboardMember -> DailyLeaderboardMember -> Bool)
-> Eq DailyLeaderboardMember
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
$c/= :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
== :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
$c== :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
Eq, Eq DailyLeaderboardMember
Eq DailyLeaderboardMember
-> (DailyLeaderboardMember -> DailyLeaderboardMember -> Ordering)
-> (DailyLeaderboardMember -> DailyLeaderboardMember -> Bool)
-> (DailyLeaderboardMember -> DailyLeaderboardMember -> Bool)
-> (DailyLeaderboardMember -> DailyLeaderboardMember -> Bool)
-> (DailyLeaderboardMember -> DailyLeaderboardMember -> Bool)
-> (DailyLeaderboardMember
    -> DailyLeaderboardMember -> DailyLeaderboardMember)
-> (DailyLeaderboardMember
    -> DailyLeaderboardMember -> DailyLeaderboardMember)
-> Ord DailyLeaderboardMember
DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
DailyLeaderboardMember -> DailyLeaderboardMember -> Ordering
DailyLeaderboardMember
-> DailyLeaderboardMember -> DailyLeaderboardMember
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: DailyLeaderboardMember
-> DailyLeaderboardMember -> DailyLeaderboardMember
$cmin :: DailyLeaderboardMember
-> DailyLeaderboardMember -> DailyLeaderboardMember
max :: DailyLeaderboardMember
-> DailyLeaderboardMember -> DailyLeaderboardMember
$cmax :: DailyLeaderboardMember
-> DailyLeaderboardMember -> DailyLeaderboardMember
>= :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
$c>= :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
> :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
$c> :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
<= :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
$c<= :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
< :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
$c< :: DailyLeaderboardMember -> DailyLeaderboardMember -> Bool
compare :: DailyLeaderboardMember -> DailyLeaderboardMember -> Ordering
$ccompare :: DailyLeaderboardMember -> DailyLeaderboardMember -> Ordering
$cp1Ord :: Eq DailyLeaderboardMember
Ord, Typeable, (forall x. DailyLeaderboardMember -> Rep DailyLeaderboardMember x)
-> (forall x.
    Rep DailyLeaderboardMember x -> DailyLeaderboardMember)
-> Generic DailyLeaderboardMember
forall x. Rep DailyLeaderboardMember x -> DailyLeaderboardMember
forall x. DailyLeaderboardMember -> Rep DailyLeaderboardMember x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DailyLeaderboardMember x -> DailyLeaderboardMember
$cfrom :: forall x. DailyLeaderboardMember -> Rep DailyLeaderboardMember x
Generic)

-- | Turn a 'dlbmDecTime' field into a 'ZonedTime' for the actual
-- completion of the puzzle, based on the year and day of event.
--
-- @since 0.2.7.0
dlbmCompleteTime :: Integer -> Day -> NominalDiffTime -> ZonedTime
dlbmCompleteTime :: Integer -> Day -> NominalDiffTime -> ZonedTime
dlbmCompleteTime Integer
y Day
d NominalDiffTime
t = ZonedTime
r
    { zonedTimeToLocalTime :: LocalTime
zonedTimeToLocalTime = Day -> NominalDiffTime -> NominalDiffTime
dlbmTime Day
d NominalDiffTime
t NominalDiffTime -> LocalTime -> LocalTime
`addLocalTime` ZonedTime -> LocalTime
zonedTimeToLocalTime ZonedTime
r
    }
  where
    r :: ZonedTime
r = Integer -> Day -> ZonedTime
challengeReleaseTime Integer
y Day
d

-- | Turn a 'dlbmDecTime' field into a 'NominalDiffTime' representing the
-- actual amount of time taken to complete the puzzle.
--
-- @since 0.2.7.0
dlbmTime :: Day -> NominalDiffTime -> NominalDiffTime
dlbmTime :: Day -> NominalDiffTime -> NominalDiffTime
dlbmTime Day
d = (Integer -> TimeOfDay -> NominalDiffTime)
-> (Integer, TimeOfDay) -> NominalDiffTime
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Integer -> TimeOfDay -> NominalDiffTime
daysAndTimeOfDayToTime
           ((Integer, TimeOfDay) -> NominalDiffTime)
-> (NominalDiffTime -> (Integer, TimeOfDay))
-> NominalDiffTime
-> NominalDiffTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer)
-> (Integer, TimeOfDay) -> (Integer, TimeOfDay)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
subtract (Day -> Integer
dayInt Day
d Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1))
           ((Integer, TimeOfDay) -> (Integer, TimeOfDay))
-> (NominalDiffTime -> (Integer, TimeOfDay))
-> NominalDiffTime
-> (Integer, TimeOfDay)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NominalDiffTime -> (Integer, TimeOfDay)
timeToDaysAndTimeOfDay

-- | Daily leaderboard, containing Star 1 and Star 2 completions
--
-- @since 0.2.3.0
data DailyLeaderboard = DLB {
    DailyLeaderboard -> Map Rank DailyLeaderboardMember
dlbStar1 :: Map Rank DailyLeaderboardMember
  , DailyLeaderboard -> Map Rank DailyLeaderboardMember
dlbStar2 :: Map Rank DailyLeaderboardMember
  }
  deriving (Int -> DailyLeaderboard -> ShowS
[DailyLeaderboard] -> ShowS
DailyLeaderboard -> String
(Int -> DailyLeaderboard -> ShowS)
-> (DailyLeaderboard -> String)
-> ([DailyLeaderboard] -> ShowS)
-> Show DailyLeaderboard
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DailyLeaderboard] -> ShowS
$cshowList :: [DailyLeaderboard] -> ShowS
show :: DailyLeaderboard -> String
$cshow :: DailyLeaderboard -> String
showsPrec :: Int -> DailyLeaderboard -> ShowS
$cshowsPrec :: Int -> DailyLeaderboard -> ShowS
Show, DailyLeaderboard -> DailyLeaderboard -> Bool
(DailyLeaderboard -> DailyLeaderboard -> Bool)
-> (DailyLeaderboard -> DailyLeaderboard -> Bool)
-> Eq DailyLeaderboard
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DailyLeaderboard -> DailyLeaderboard -> Bool
$c/= :: DailyLeaderboard -> DailyLeaderboard -> Bool
== :: DailyLeaderboard -> DailyLeaderboard -> Bool
$c== :: DailyLeaderboard -> DailyLeaderboard -> Bool
Eq, Eq DailyLeaderboard
Eq DailyLeaderboard
-> (DailyLeaderboard -> DailyLeaderboard -> Ordering)
-> (DailyLeaderboard -> DailyLeaderboard -> Bool)
-> (DailyLeaderboard -> DailyLeaderboard -> Bool)
-> (DailyLeaderboard -> DailyLeaderboard -> Bool)
-> (DailyLeaderboard -> DailyLeaderboard -> Bool)
-> (DailyLeaderboard -> DailyLeaderboard -> DailyLeaderboard)
-> (DailyLeaderboard -> DailyLeaderboard -> DailyLeaderboard)
-> Ord DailyLeaderboard
DailyLeaderboard -> DailyLeaderboard -> Bool
DailyLeaderboard -> DailyLeaderboard -> Ordering
DailyLeaderboard -> DailyLeaderboard -> DailyLeaderboard
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: DailyLeaderboard -> DailyLeaderboard -> DailyLeaderboard
$cmin :: DailyLeaderboard -> DailyLeaderboard -> DailyLeaderboard
max :: DailyLeaderboard -> DailyLeaderboard -> DailyLeaderboard
$cmax :: DailyLeaderboard -> DailyLeaderboard -> DailyLeaderboard
>= :: DailyLeaderboard -> DailyLeaderboard -> Bool
$c>= :: DailyLeaderboard -> DailyLeaderboard -> Bool
> :: DailyLeaderboard -> DailyLeaderboard -> Bool
$c> :: DailyLeaderboard -> DailyLeaderboard -> Bool
<= :: DailyLeaderboard -> DailyLeaderboard -> Bool
$c<= :: DailyLeaderboard -> DailyLeaderboard -> Bool
< :: DailyLeaderboard -> DailyLeaderboard -> Bool
$c< :: DailyLeaderboard -> DailyLeaderboard -> Bool
compare :: DailyLeaderboard -> DailyLeaderboard -> Ordering
$ccompare :: DailyLeaderboard -> DailyLeaderboard -> Ordering
$cp1Ord :: Eq DailyLeaderboard
Ord, Typeable, (forall x. DailyLeaderboard -> Rep DailyLeaderboard x)
-> (forall x. Rep DailyLeaderboard x -> DailyLeaderboard)
-> Generic DailyLeaderboard
forall x. Rep DailyLeaderboard x -> DailyLeaderboard
forall x. DailyLeaderboard -> Rep DailyLeaderboard x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DailyLeaderboard x -> DailyLeaderboard
$cfrom :: forall x. DailyLeaderboard -> Rep DailyLeaderboard x
Generic)

-- | Single global leaderboard position
--
-- @since 0.2.3.0
data GlobalLeaderboardMember = GLBM
    { GlobalLeaderboardMember -> Rank
glbmRank      :: Rank
    , GlobalLeaderboardMember -> Integer
glbmScore     :: Integer
    , GlobalLeaderboardMember -> Either Integer Text
glbmUser      :: Either Integer Text
    , GlobalLeaderboardMember -> Maybe Text
glbmLink      :: Maybe Text
    , GlobalLeaderboardMember -> Maybe Text
glbmImage     :: Maybe Text
    , GlobalLeaderboardMember -> Bool
glbmSupporter :: Bool
    }
  deriving (Int -> GlobalLeaderboardMember -> ShowS
[GlobalLeaderboardMember] -> ShowS
GlobalLeaderboardMember -> String
(Int -> GlobalLeaderboardMember -> ShowS)
-> (GlobalLeaderboardMember -> String)
-> ([GlobalLeaderboardMember] -> ShowS)
-> Show GlobalLeaderboardMember
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GlobalLeaderboardMember] -> ShowS
$cshowList :: [GlobalLeaderboardMember] -> ShowS
show :: GlobalLeaderboardMember -> String
$cshow :: GlobalLeaderboardMember -> String
showsPrec :: Int -> GlobalLeaderboardMember -> ShowS
$cshowsPrec :: Int -> GlobalLeaderboardMember -> ShowS
Show, GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
(GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool)
-> (GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool)
-> Eq GlobalLeaderboardMember
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
$c/= :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
== :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
$c== :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
Eq, Eq GlobalLeaderboardMember
Eq GlobalLeaderboardMember
-> (GlobalLeaderboardMember -> GlobalLeaderboardMember -> Ordering)
-> (GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool)
-> (GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool)
-> (GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool)
-> (GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool)
-> (GlobalLeaderboardMember
    -> GlobalLeaderboardMember -> GlobalLeaderboardMember)
-> (GlobalLeaderboardMember
    -> GlobalLeaderboardMember -> GlobalLeaderboardMember)
-> Ord GlobalLeaderboardMember
GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
GlobalLeaderboardMember -> GlobalLeaderboardMember -> Ordering
GlobalLeaderboardMember
-> GlobalLeaderboardMember -> GlobalLeaderboardMember
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: GlobalLeaderboardMember
-> GlobalLeaderboardMember -> GlobalLeaderboardMember
$cmin :: GlobalLeaderboardMember
-> GlobalLeaderboardMember -> GlobalLeaderboardMember
max :: GlobalLeaderboardMember
-> GlobalLeaderboardMember -> GlobalLeaderboardMember
$cmax :: GlobalLeaderboardMember
-> GlobalLeaderboardMember -> GlobalLeaderboardMember
>= :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
$c>= :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
> :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
$c> :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
<= :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
$c<= :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
< :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
$c< :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Bool
compare :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Ordering
$ccompare :: GlobalLeaderboardMember -> GlobalLeaderboardMember -> Ordering
$cp1Ord :: Eq GlobalLeaderboardMember
Ord, Typeable, (forall x.
 GlobalLeaderboardMember -> Rep GlobalLeaderboardMember x)
-> (forall x.
    Rep GlobalLeaderboardMember x -> GlobalLeaderboardMember)
-> Generic GlobalLeaderboardMember
forall x. Rep GlobalLeaderboardMember x -> GlobalLeaderboardMember
forall x. GlobalLeaderboardMember -> Rep GlobalLeaderboardMember x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep GlobalLeaderboardMember x -> GlobalLeaderboardMember
$cfrom :: forall x. GlobalLeaderboardMember -> Rep GlobalLeaderboardMember x
Generic)

-- | Global leaderboard for the entire event
--
-- Under each 'Rank' is an 'Integer' for the score at that rank, as well as
-- a non-empty list of all members who achieved that rank and score.
--
-- @since 0.2.3.0
newtype GlobalLeaderboard = GLB {
    GlobalLeaderboard
-> Map Rank (Integer, NonEmpty GlobalLeaderboardMember)
glbMap :: Map Rank (Integer, NonEmpty GlobalLeaderboardMember)
  }
  deriving (Int -> GlobalLeaderboard -> ShowS
[GlobalLeaderboard] -> ShowS
GlobalLeaderboard -> String
(Int -> GlobalLeaderboard -> ShowS)
-> (GlobalLeaderboard -> String)
-> ([GlobalLeaderboard] -> ShowS)
-> Show GlobalLeaderboard
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GlobalLeaderboard] -> ShowS
$cshowList :: [GlobalLeaderboard] -> ShowS
show :: GlobalLeaderboard -> String
$cshow :: GlobalLeaderboard -> String
showsPrec :: Int -> GlobalLeaderboard -> ShowS
$cshowsPrec :: Int -> GlobalLeaderboard -> ShowS
Show, GlobalLeaderboard -> GlobalLeaderboard -> Bool
(GlobalLeaderboard -> GlobalLeaderboard -> Bool)
-> (GlobalLeaderboard -> GlobalLeaderboard -> Bool)
-> Eq GlobalLeaderboard
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
$c/= :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
== :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
$c== :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
Eq, Eq GlobalLeaderboard
Eq GlobalLeaderboard
-> (GlobalLeaderboard -> GlobalLeaderboard -> Ordering)
-> (GlobalLeaderboard -> GlobalLeaderboard -> Bool)
-> (GlobalLeaderboard -> GlobalLeaderboard -> Bool)
-> (GlobalLeaderboard -> GlobalLeaderboard -> Bool)
-> (GlobalLeaderboard -> GlobalLeaderboard -> Bool)
-> (GlobalLeaderboard -> GlobalLeaderboard -> GlobalLeaderboard)
-> (GlobalLeaderboard -> GlobalLeaderboard -> GlobalLeaderboard)
-> Ord GlobalLeaderboard
GlobalLeaderboard -> GlobalLeaderboard -> Bool
GlobalLeaderboard -> GlobalLeaderboard -> Ordering
GlobalLeaderboard -> GlobalLeaderboard -> GlobalLeaderboard
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: GlobalLeaderboard -> GlobalLeaderboard -> GlobalLeaderboard
$cmin :: GlobalLeaderboard -> GlobalLeaderboard -> GlobalLeaderboard
max :: GlobalLeaderboard -> GlobalLeaderboard -> GlobalLeaderboard
$cmax :: GlobalLeaderboard -> GlobalLeaderboard -> GlobalLeaderboard
>= :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
$c>= :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
> :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
$c> :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
<= :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
$c<= :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
< :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
$c< :: GlobalLeaderboard -> GlobalLeaderboard -> Bool
compare :: GlobalLeaderboard -> GlobalLeaderboard -> Ordering
$ccompare :: GlobalLeaderboard -> GlobalLeaderboard -> Ordering
$cp1Ord :: Eq GlobalLeaderboard
Ord, Typeable, (forall x. GlobalLeaderboard -> Rep GlobalLeaderboard x)
-> (forall x. Rep GlobalLeaderboard x -> GlobalLeaderboard)
-> Generic GlobalLeaderboard
forall x. Rep GlobalLeaderboard x -> GlobalLeaderboard
forall x. GlobalLeaderboard -> Rep GlobalLeaderboard x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep GlobalLeaderboard x -> GlobalLeaderboard
$cfrom :: forall x. GlobalLeaderboard -> Rep GlobalLeaderboard x
Generic)

-- | The next day for a challenge in a given year, and also the number of
-- seconds until the challenge is released.
--
-- @since 0.2.8.0
data NextDayTime = NextDayTime Day Int
                 | NoNextDayTime
  deriving (Int -> NextDayTime -> ShowS
[NextDayTime] -> ShowS
NextDayTime -> String
(Int -> NextDayTime -> ShowS)
-> (NextDayTime -> String)
-> ([NextDayTime] -> ShowS)
-> Show NextDayTime
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NextDayTime] -> ShowS
$cshowList :: [NextDayTime] -> ShowS
show :: NextDayTime -> String
$cshow :: NextDayTime -> String
showsPrec :: Int -> NextDayTime -> ShowS
$cshowsPrec :: Int -> NextDayTime -> ShowS
Show, NextDayTime -> NextDayTime -> Bool
(NextDayTime -> NextDayTime -> Bool)
-> (NextDayTime -> NextDayTime -> Bool) -> Eq NextDayTime
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NextDayTime -> NextDayTime -> Bool
$c/= :: NextDayTime -> NextDayTime -> Bool
== :: NextDayTime -> NextDayTime -> Bool
$c== :: NextDayTime -> NextDayTime -> Bool
Eq, Eq NextDayTime
Eq NextDayTime
-> (NextDayTime -> NextDayTime -> Ordering)
-> (NextDayTime -> NextDayTime -> Bool)
-> (NextDayTime -> NextDayTime -> Bool)
-> (NextDayTime -> NextDayTime -> Bool)
-> (NextDayTime -> NextDayTime -> Bool)
-> (NextDayTime -> NextDayTime -> NextDayTime)
-> (NextDayTime -> NextDayTime -> NextDayTime)
-> Ord NextDayTime
NextDayTime -> NextDayTime -> Bool
NextDayTime -> NextDayTime -> Ordering
NextDayTime -> NextDayTime -> NextDayTime
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NextDayTime -> NextDayTime -> NextDayTime
$cmin :: NextDayTime -> NextDayTime -> NextDayTime
max :: NextDayTime -> NextDayTime -> NextDayTime
$cmax :: NextDayTime -> NextDayTime -> NextDayTime
>= :: NextDayTime -> NextDayTime -> Bool
$c>= :: NextDayTime -> NextDayTime -> Bool
> :: NextDayTime -> NextDayTime -> Bool
$c> :: NextDayTime -> NextDayTime -> Bool
<= :: NextDayTime -> NextDayTime -> Bool
$c<= :: NextDayTime -> NextDayTime -> Bool
< :: NextDayTime -> NextDayTime -> Bool
$c< :: NextDayTime -> NextDayTime -> Bool
compare :: NextDayTime -> NextDayTime -> Ordering
$ccompare :: NextDayTime -> NextDayTime -> Ordering
$cp1Ord :: Eq NextDayTime
Ord, Typeable, (forall x. NextDayTime -> Rep NextDayTime x)
-> (forall x. Rep NextDayTime x -> NextDayTime)
-> Generic NextDayTime
forall x. Rep NextDayTime x -> NextDayTime
forall x. NextDayTime -> Rep NextDayTime x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep NextDayTime x -> NextDayTime
$cfrom :: forall x. NextDayTime -> Rep NextDayTime x
Generic)

instance ToHttpApiData Part where
    toUrlPiece :: Part -> Text
toUrlPiece = String -> Text
T.pack (String -> Text) -> (Part -> String) -> Part -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show (Int -> String) -> (Part -> Int) -> Part -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Part -> Int
partInt
    toQueryParam :: Part -> Text
toQueryParam = Part -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece

instance ToHttpApiData Day where
    toUrlPiece :: Day -> Text
toUrlPiece = String -> Text
T.pack (String -> Text) -> (Day -> String) -> Day -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> String
forall a. Show a => a -> String
show (Integer -> String) -> (Day -> Integer) -> Day -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Integer
dayInt
    toQueryParam :: Day -> Text
toQueryParam = Day -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece

instance ToHttpApiData PublicCode where
    toUrlPiece :: PublicCode -> Text
toUrlPiece   = (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".json") (Text -> Text) -> (PublicCode -> Text) -> PublicCode -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> (PublicCode -> String) -> PublicCode -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> String
forall a. Show a => a -> String
show (Integer -> String)
-> (PublicCode -> Integer) -> PublicCode -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicCode -> Integer
getPublicCode
    toQueryParam :: PublicCode -> Text
toQueryParam = PublicCode -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece

instance WF.ToForm SubmitInfo where
    toForm :: SubmitInfo -> Form
toForm = FormOptions -> SubmitInfo -> Form
forall a.
(Generic a, GToForm a (Rep a)) =>
FormOptions -> a -> Form
WF.genericToForm FormOptions :: ShowS -> FormOptions
WF.FormOptions
      { fieldLabelModifier :: ShowS
WF.fieldLabelModifier = Char -> ShowS
camelTo2 Char
'-' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
2 }

instance FromJSON Leaderboard where
    parseJSON :: Value -> Parser Leaderboard
parseJSON = String
-> (Object -> Parser Leaderboard) -> Value -> Parser Leaderboard
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"Leaderboard" ((Object -> Parser Leaderboard) -> Value -> Parser Leaderboard)
-> (Object -> Parser Leaderboard) -> Value -> Parser Leaderboard
forall a b. (a -> b) -> a -> b
$ \Object
o ->
        Integer -> Integer -> Map Integer LeaderboardMember -> Leaderboard
LB (Integer
 -> Integer -> Map Integer LeaderboardMember -> Leaderboard)
-> Parser Integer
-> Parser (Integer -> Map Integer LeaderboardMember -> Leaderboard)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> Parser Integer
forall a (m :: * -> *). (Read a, MonadFail m) => String -> m a
strInt (String -> Parser Integer) -> Parser String -> Parser Integer
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Object
o Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"event"))
           Parser (Integer -> Map Integer LeaderboardMember -> Leaderboard)
-> Parser Integer
-> Parser (Map Integer LeaderboardMember -> Leaderboard)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> Parser Integer
forall a (m :: * -> *). (Read a, MonadFail m) => String -> m a
strInt (String -> Parser Integer) -> Parser String -> Parser Integer
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Object
o Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"owner_id"))
           Parser (Map Integer LeaderboardMember -> Leaderboard)
-> Parser (Map Integer LeaderboardMember) -> Parser Leaderboard
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser (Map Integer LeaderboardMember)
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"members"
      where
        strInt :: String -> m a
strInt String
t = case String -> Maybe a
forall a. Read a => String -> Maybe a
readMaybe String
t of
          Maybe a
Nothing -> String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"bad int"
          Just a
i  -> a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
i

instance FromJSON LeaderboardMember where
    parseJSON :: Value -> Parser LeaderboardMember
parseJSON = String
-> (Object -> Parser LeaderboardMember)
-> Value
-> Parser LeaderboardMember
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"LeaderboardMember" ((Object -> Parser LeaderboardMember)
 -> Value -> Parser LeaderboardMember)
-> (Object -> Parser LeaderboardMember)
-> Value
-> Parser LeaderboardMember
forall a b. (a -> b) -> a -> b
$ \Object
o ->
        Integer
-> Maybe Text
-> Integer
-> Integer
-> Maybe UTCTime
-> Int
-> Map Day (Map Part UTCTime)
-> LeaderboardMember
LBM (Integer
 -> Maybe Text
 -> Integer
 -> Integer
 -> Maybe UTCTime
 -> Int
 -> Map Day (Map Part UTCTime)
 -> LeaderboardMember)
-> Parser Integer
-> Parser
     (Maybe Text
      -> Integer
      -> Integer
      -> Maybe UTCTime
      -> Int
      -> Map Day (Map Part UTCTime)
      -> LeaderboardMember)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser Integer
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"global_score"
            Parser
  (Maybe Text
   -> Integer
   -> Integer
   -> Maybe UTCTime
   -> Int
   -> Map Day (Map Part UTCTime)
   -> LeaderboardMember)
-> Parser (Maybe Text)
-> Parser
     (Integer
      -> Integer
      -> Maybe UTCTime
      -> Int
      -> Map Day (Map Part UTCTime)
      -> LeaderboardMember)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Text -> Parser (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"name")
            Parser
  (Integer
   -> Integer
   -> Maybe UTCTime
   -> Int
   -> Map Day (Map Part UTCTime)
   -> LeaderboardMember)
-> Parser Integer
-> Parser
     (Integer
      -> Maybe UTCTime
      -> Int
      -> Map Day (Map Part UTCTime)
      -> LeaderboardMember)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser Integer
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"local_score"
            Parser
  (Integer
   -> Maybe UTCTime
   -> Int
   -> Map Day (Map Part UTCTime)
   -> LeaderboardMember)
-> Parser Integer
-> Parser
     (Maybe UTCTime
      -> Int -> Map Day (Map Part UTCTime) -> LeaderboardMember)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> Parser Integer
forall a (m :: * -> *). (Read a, MonadFail m) => String -> m a
strInt (String -> Parser Integer) -> Parser String -> Parser Integer
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Object
o Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"id"))
            Parser
  (Maybe UTCTime
   -> Int -> Map Day (Map Part UTCTime) -> LeaderboardMember)
-> Parser (Maybe UTCTime)
-> Parser (Int -> Map Day (Map Part UTCTime) -> LeaderboardMember)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser UTCTime -> Parser (Maybe UTCTime)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (String -> Parser UTCTime
forall (m :: * -> *). MonadFail m => String -> m UTCTime
fromEpoch (String -> Parser UTCTime) -> Parser String -> Parser UTCTime
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Object
o Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"last_star_ts"))
            Parser (Int -> Map Day (Map Part UTCTime) -> LeaderboardMember)
-> Parser Int
-> Parser (Map Day (Map Part UTCTime) -> LeaderboardMember)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser Int
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"stars"
            Parser (Map Day (Map Part UTCTime) -> LeaderboardMember)
-> Parser (Map Day (Map Part UTCTime)) -> Parser LeaderboardMember
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (do Map Day (Map Part Object)
cdl <- Object
o Object -> Text -> Parser (Map Day (Map Part Object))
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"completion_day_level"
                    ((Map Part Object -> Parser (Map Part UTCTime))
-> Map Day (Map Part Object) -> Parser (Map Day (Map Part UTCTime))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((Map Part Object -> Parser (Map Part UTCTime))
 -> Map Day (Map Part Object)
 -> Parser (Map Day (Map Part UTCTime)))
-> ((Object -> Parser UTCTime)
    -> Map Part Object -> Parser (Map Part UTCTime))
-> (Object -> Parser UTCTime)
-> Map Day (Map Part Object)
-> Parser (Map Day (Map Part UTCTime))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Object -> Parser UTCTime)
-> Map Part Object -> Parser (Map Part UTCTime)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse) ((String -> Parser UTCTime
forall (m :: * -> *). MonadFail m => String -> m UTCTime
fromEpoch (String -> Parser UTCTime) -> Parser String -> Parser UTCTime
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) (Parser String -> Parser UTCTime)
-> (Object -> Parser String) -> Object -> Parser UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Object -> Text -> Parser String
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"get_star_ts")) Map Day (Map Part Object)
cdl
                )
      where
        strInt :: String -> m a
strInt String
t = case String -> Maybe a
forall a. Read a => String -> Maybe a
readMaybe String
t of
          Maybe a
Nothing -> String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"bad int"
          Just a
i  -> a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
i
        fromEpoch :: String -> m UTCTime
fromEpoch String
t = case String -> Maybe Integer
forall a. Read a => String -> Maybe a
readMaybe String
t of
          Maybe Integer
Nothing -> String -> m UTCTime
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"bad stamp"
          Just Integer
i  -> UTCTime -> m UTCTime
forall (f :: * -> *) a. Applicative f => a -> f a
pure (UTCTime -> m UTCTime)
-> (NominalDiffTime -> UTCTime) -> NominalDiffTime -> m UTCTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NominalDiffTime -> UTCTime
posixSecondsToUTCTime (NominalDiffTime -> m UTCTime) -> NominalDiffTime -> m UTCTime
forall a b. (a -> b) -> a -> b
$ Integer -> NominalDiffTime
forall a. Num a => Integer -> a
fromInteger Integer
i

-- | @since 0.2.4.2
instance ToJSONKey Day where
    toJSONKey :: ToJSONKeyFunction Day
toJSONKey = (Day -> Text) -> ToJSONKeyFunction Day
forall a. (a -> Text) -> ToJSONKeyFunction a
toJSONKeyText ((Day -> Text) -> ToJSONKeyFunction Day)
-> (Day -> Text) -> ToJSONKeyFunction Day
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack (String -> Text) -> (Day -> String) -> Day -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> String
forall a. Show a => a -> String
show (Integer -> String) -> (Day -> Integer) -> Day -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Integer
dayInt
instance FromJSONKey Day where
    fromJSONKey :: FromJSONKeyFunction Day
fromJSONKey = (Text -> Parser Day) -> FromJSONKeyFunction Day
forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser (Value -> Parser Day
forall a. FromJSON a => Value -> Parser a
parseJSON (Value -> Parser Day) -> (Text -> Value) -> Text -> Parser Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Value
String)
-- | @since 0.2.4.2
instance ToJSONKey Part where
    toJSONKey :: ToJSONKeyFunction Part
toJSONKey = (Part -> Text) -> ToJSONKeyFunction Part
forall a. (a -> Text) -> ToJSONKeyFunction a
toJSONKeyText ((Part -> Text) -> ToJSONKeyFunction Part)
-> (Part -> Text) -> ToJSONKeyFunction Part
forall a b. (a -> b) -> a -> b
$ \case
      Part
Part1 -> Text
"1"
      Part
Part2 -> Text
"2"
instance FromJSONKey Part where
    fromJSONKey :: FromJSONKeyFunction Part
fromJSONKey = (Text -> Parser Part) -> FromJSONKeyFunction Part
forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser (Value -> Parser Part
forall a. FromJSON a => Value -> Parser a
parseJSON (Value -> Parser Part) -> (Text -> Value) -> Text -> Parser Part
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Value
String)

-- | @since 0.2.4.2
instance ToJSON Part where
    toJSON :: Part -> Value
toJSON = Text -> Value
String (Text -> Value) -> (Part -> Text) -> Part -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\case Part
Part1 -> Text
"1"; Part
Part2 -> Text
"2")
instance FromJSON Part where
    parseJSON :: Value -> Parser Part
parseJSON = String -> (Text -> Parser Part) -> Value -> Parser Part
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"Part" ((Text -> Parser Part) -> Value -> Parser Part)
-> (Text -> Parser Part) -> Value -> Parser Part
forall a b. (a -> b) -> a -> b
$ \case
      Text
"1" -> Part -> Parser Part
forall (f :: * -> *) a. Applicative f => a -> f a
pure Part
Part1
      Text
"2" -> Part -> Parser Part
forall (f :: * -> *) a. Applicative f => a -> f a
pure Part
Part2
      Text
_   -> String -> Parser Part
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Bad part"

-- | @since 0.2.4.2
instance ToJSON Day where
    toJSON :: Day -> Value
toJSON = Text -> Value
String (Text -> Value) -> (Day -> Text) -> Day -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> (Day -> String) -> Day -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> String
forall a. Show a => a -> String
show (Integer -> String) -> (Day -> Integer) -> Day -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Integer
dayInt
instance FromJSON Day where
    parseJSON :: Value -> Parser Day
parseJSON = String -> (Text -> Parser Day) -> Value -> Parser Day
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"Day" ((Text -> Parser Day) -> Value -> Parser Day)
-> (Text -> Parser Day) -> Value -> Parser Day
forall a b. (a -> b) -> a -> b
$ \Text
t ->
      case String -> Maybe Integer
forall a. Read a => String -> Maybe a
readMaybe (Text -> String
T.unpack Text
t) of
        Maybe Integer
Nothing -> String -> Parser Day
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"No read day"
        Just Integer
i  -> case Integer -> Maybe Day
mkDay Integer
i of
          Maybe Day
Nothing -> String -> Parser Day
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Day out of range"
          Just Day
d  -> Day -> Parser Day
forall (f :: * -> *) a. Applicative f => a -> f a
pure Day
d

instance ToJSONKey Rank where
    toJSONKey :: ToJSONKeyFunction Rank
toJSONKey = (Rank -> Text) -> ToJSONKeyFunction Rank
forall a. (a -> Text) -> ToJSONKeyFunction a
toJSONKeyText ((Rank -> Text) -> ToJSONKeyFunction Rank)
-> (Rank -> Text) -> ToJSONKeyFunction Rank
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack (String -> Text) -> (Rank -> String) -> Rank -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> String
forall a. Show a => a -> String
show (Integer -> String) -> (Rank -> Integer) -> Rank -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1) (Integer -> Integer) -> (Rank -> Integer) -> Rank -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Finite 100 -> Integer
forall (n :: Nat). Finite n -> Integer
getFinite (Finite 100 -> Integer) -> (Rank -> Finite 100) -> Rank -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rank -> Finite 100
getRank
instance FromJSONKey Rank where
    fromJSONKey :: FromJSONKeyFunction Rank
fromJSONKey = (Text -> Parser Rank) -> FromJSONKeyFunction Rank
forall a. (Text -> Parser a) -> FromJSONKeyFunction a
FromJSONKeyTextParser (Value -> Parser Rank
forall a. FromJSON a => Value -> Parser a
parseJSON (Value -> Parser Rank) -> (Text -> Value) -> Text -> Parser Rank
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Value
String)

instance ToJSON Rank where
    toJSON :: Rank -> Value
toJSON = Text -> Value
String (Text -> Value) -> (Rank -> Text) -> Rank -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> (Rank -> String) -> Rank -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> String
forall a. Show a => a -> String
show (Integer -> String) -> (Rank -> Integer) -> Rank -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1) (Integer -> Integer) -> (Rank -> Integer) -> Rank -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Finite 100 -> Integer
forall (n :: Nat). Finite n -> Integer
getFinite (Finite 100 -> Integer) -> (Rank -> Finite 100) -> Rank -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rank -> Finite 100
getRank
instance FromJSON Rank where
    parseJSON :: Value -> Parser Rank
parseJSON = String -> (Text -> Parser Rank) -> Value -> Parser Rank
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"Rank" ((Text -> Parser Rank) -> Value -> Parser Rank)
-> (Text -> Parser Rank) -> Value -> Parser Rank
forall a b. (a -> b) -> a -> b
$ \Text
t ->
      case String -> Maybe Integer
forall a. Read a => String -> Maybe a
readMaybe (Text -> String
T.unpack Text
t) of
        Maybe Integer
Nothing -> String -> Parser Rank
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"No read rank"
        Just Integer
i  -> case Integer -> Maybe (Finite 100)
forall (n :: Nat). KnownNat n => Integer -> Maybe (Finite n)
packFinite (Integer
i Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1) of
          Maybe (Finite 100)
Nothing -> String -> Parser Rank
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Rank out of range"
          Just Finite 100
d  -> Rank -> Parser Rank
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Rank -> Parser Rank) -> Rank -> Parser Rank
forall a b. (a -> b) -> a -> b
$ Finite 100 -> Rank
Rank Finite 100
d

instance ToJSON DailyLeaderboard where
    toJSON :: DailyLeaderboard -> Value
toJSON = Options -> DailyLeaderboard -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
defaultOptions
        { fieldLabelModifier :: ShowS
fieldLabelModifier = Char -> ShowS
camelTo2 Char
'-' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
3 }
instance FromJSON DailyLeaderboard where
    parseJSON :: Value -> Parser DailyLeaderboard
parseJSON = Options -> Value -> Parser DailyLeaderboard
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions
        { fieldLabelModifier :: ShowS
fieldLabelModifier = Char -> ShowS
camelTo2 Char
'-' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
3 }

instance ToJSON GlobalLeaderboard where
    toJSON :: GlobalLeaderboard -> Value
toJSON = Options -> GlobalLeaderboard -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
defaultOptions
        { fieldLabelModifier :: ShowS
fieldLabelModifier = Char -> ShowS
camelTo2 Char
'-' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
3 }
instance FromJSON GlobalLeaderboard where
    parseJSON :: Value -> Parser GlobalLeaderboard
parseJSON = Options -> Value -> Parser GlobalLeaderboard
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions
        { fieldLabelModifier :: ShowS
fieldLabelModifier = Char -> ShowS
camelTo2 Char
'-' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
3 }

instance ToJSON DailyLeaderboardMember where
    toJSON :: DailyLeaderboardMember -> Value
toJSON = Options -> DailyLeaderboardMember -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
defaultOptions
        { fieldLabelModifier :: ShowS
fieldLabelModifier = Char -> ShowS
camelTo2 Char
'-' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
4 }
instance FromJSON DailyLeaderboardMember where
    parseJSON :: Value -> Parser DailyLeaderboardMember
parseJSON = Options -> Value -> Parser DailyLeaderboardMember
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions
        { fieldLabelModifier :: ShowS
fieldLabelModifier = Char -> ShowS
camelTo2 Char
'-' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
4 }

instance ToJSON GlobalLeaderboardMember where
    toJSON :: GlobalLeaderboardMember -> Value
toJSON = Options -> GlobalLeaderboardMember -> Value
forall a.
(Generic a, GToJSON' Value Zero (Rep a)) =>
Options -> a -> Value
genericToJSON Options
defaultOptions
        { fieldLabelModifier :: ShowS
fieldLabelModifier = Char -> ShowS
camelTo2 Char
'-' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
4 }
instance FromJSON GlobalLeaderboardMember where
    parseJSON :: Value -> Parser GlobalLeaderboardMember
parseJSON = Options -> Value -> Parser GlobalLeaderboardMember
forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON Options
defaultOptions
        { fieldLabelModifier :: ShowS
fieldLabelModifier = Char -> ShowS
camelTo2 Char
'-' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Int -> [a] -> [a]
drop Int
4 }

-- | Parse 'T.Text' into a 'SubmitRes'.
parseSubmitRes :: Text -> SubmitRes
parseSubmitRes :: Text -> SubmitRes
parseSubmitRes = (ParseErrorBundle Text Void -> SubmitRes)
-> (SubmitRes -> SubmitRes)
-> Either (ParseErrorBundle Text Void) SubmitRes
-> SubmitRes
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> SubmitRes
SubUnknown (String -> SubmitRes)
-> (ParseErrorBundle Text Void -> String)
-> ParseErrorBundle Text Void
-> SubmitRes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseErrorBundle Text Void -> String
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
P.errorBundlePretty) SubmitRes -> SubmitRes
forall a. a -> a
id
               (Either (ParseErrorBundle Text Void) SubmitRes -> SubmitRes)
-> (Text -> Either (ParseErrorBundle Text Void) SubmitRes)
-> Text
-> SubmitRes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parsec Void Text SubmitRes
-> String -> Text -> Either (ParseErrorBundle Text Void) SubmitRes
forall e s a.
Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
P.runParser Parsec Void Text SubmitRes
choices String
"Submission Response"
               (Text -> Either (ParseErrorBundle Text Void) SubmitRes)
-> (Text -> Text)
-> Text
-> Either (ParseErrorBundle Text Void) SubmitRes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
               ([Text] -> Text) -> (Text -> [Text]) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Tag Text -> Maybe Text) -> [Tag Text] -> [Text]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Tag Text -> Maybe Text
forall a. Tag a -> Maybe a
deTag
               ([Tag Text] -> [Text]) -> (Text -> [Tag Text]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Tag Text]
forall str. StringLike str => str -> [Tag str]
H.parseTags
  where
    deTag :: Tag a -> Maybe a
deTag (H.TagText a
t) = a -> Maybe a
forall a. a -> Maybe a
Just a
t
    deTag Tag a
_             = Maybe a
forall a. Maybe a
Nothing
    choices :: Parsec Void Text SubmitRes
choices             = [Parsec Void Text SubmitRes] -> Parsec Void Text SubmitRes
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum [ Parsec Void Text SubmitRes -> Parsec Void Text SubmitRes
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
P.try Parsec Void Text SubmitRes
parseCorrect   Parsec Void Text SubmitRes -> String -> Parsec Void Text SubmitRes
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
P.<?> String
"Correct"
                               , Parsec Void Text SubmitRes -> Parsec Void Text SubmitRes
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
P.try Parsec Void Text SubmitRes
parseIncorrect Parsec Void Text SubmitRes -> String -> Parsec Void Text SubmitRes
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
P.<?> String
"Incorrect"
                               , Parsec Void Text SubmitRes -> Parsec Void Text SubmitRes
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
P.try Parsec Void Text SubmitRes
parseWait      Parsec Void Text SubmitRes -> String -> Parsec Void Text SubmitRes
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
P.<?> String
"Wait"
                               ,       Parsec Void Text SubmitRes
parseInvalid   Parsec Void Text SubmitRes -> String -> Parsec Void Text SubmitRes
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
P.<?> String
"Invalid"
                               ]
    parseCorrect :: P.Parsec Void Text SubmitRes
    parseCorrect :: Parsec Void Text SubmitRes
parseCorrect = do
      String
_ <- ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity String
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
P.manyTill ParsecT Void Text Identity Char
forall e s (m :: * -> *). MonadParsec e s m => m (Token s)
P.anySingle (Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
(MonadParsec e s m, FoldCase (Tokens s)) =>
Tokens s -> m (Tokens s)
P.string' Tokens Text
"that's the right answer") ParsecT Void Text Identity String
-> String -> ParsecT Void Text Identity String
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
P.<?> String
"Right answer"
      Maybe Integer
r <- ParsecT Void Text Identity Integer
-> ParsecT Void Text Identity (Maybe Integer)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ParsecT Void Text Identity Integer
 -> ParsecT Void Text Identity (Maybe Integer))
-> (ParsecT Void Text Identity Integer
    -> ParsecT Void Text Identity Integer)
-> ParsecT Void Text Identity Integer
-> ParsecT Void Text Identity (Maybe Integer)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ParsecT Void Text Identity Integer
-> String -> ParsecT Void Text Identity Integer
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
P.<?> String
"Rank") (ParsecT Void Text Identity Integer
 -> ParsecT Void Text Identity Integer)
-> (ParsecT Void Text Identity Integer
    -> ParsecT Void Text Identity Integer)
-> ParsecT Void Text Identity Integer
-> ParsecT Void Text Identity Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT Void Text Identity Integer
-> ParsecT Void Text Identity Integer
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
P.try (ParsecT Void Text Identity Integer
 -> ParsecT Void Text Identity (Maybe Integer))
-> ParsecT Void Text Identity Integer
-> ParsecT Void Text Identity (Maybe Integer)
forall a b. (a -> b) -> a -> b
$ do
        ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity String
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
P.manyTill ParsecT Void Text Identity Char
forall e s (m :: * -> *). MonadParsec e s m => m (Token s)
P.anySingle (Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
(MonadParsec e s m, FoldCase (Tokens s)) =>
Tokens s -> m (Tokens s)
P.string' Tokens Text
"rank")
          ParsecT Void Text Identity String
-> ParsecT Void Text Identity () -> ParsecT Void Text Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void Text Identity Char -> ParsecT Void Text Identity ()
forall (m :: * -> *) a. MonadPlus m => m a -> m ()
P.skipMany ((Token Text -> Bool) -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
(Token s -> Bool) -> m (Token s)
P.satisfy (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isDigit))
        ParsecT Void Text Identity Integer
forall e s (m :: * -> *) a.
(MonadParsec e s m, Token s ~ Char, Num a) =>
m a
P.decimal
      SubmitRes -> Parsec Void Text SubmitRes
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SubmitRes -> Parsec Void Text SubmitRes)
-> SubmitRes -> Parsec Void Text SubmitRes
forall a b. (a -> b) -> a -> b
$ Maybe Integer -> SubmitRes
SubCorrect Maybe Integer
r
    parseIncorrect :: Parsec Void Text SubmitRes
parseIncorrect = do
      String
_ <- ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity String
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
P.manyTill ParsecT Void Text Identity Char
forall e s (m :: * -> *). MonadParsec e s m => m (Token s)
P.anySingle (Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
(MonadParsec e s m, FoldCase (Tokens s)) =>
Tokens s -> m (Tokens s)
P.string' Tokens Text
"that's not the right answer") ParsecT Void Text Identity String
-> String -> ParsecT Void Text Identity String
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
P.<?> String
"Not the right answer"
      Maybe Text
hint <- ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ParsecT Void Text Identity Text
 -> ParsecT Void Text Identity (Maybe Text))
-> (ParsecT Void Text Identity Text
    -> ParsecT Void Text Identity Text)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Maybe Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ParsecT Void Text Identity Text
-> String -> ParsecT Void Text Identity Text
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
P.<?> String
"Hint") (ParsecT Void Text Identity Text
 -> ParsecT Void Text Identity Text)
-> (ParsecT Void Text Identity Text
    -> ParsecT Void Text Identity Text)
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT Void Text Identity Text -> ParsecT Void Text Identity Text
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
P.try (ParsecT Void Text Identity Text
 -> ParsecT Void Text Identity (Maybe Text))
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity (Maybe Text)
forall a b. (a -> b) -> a -> b
$ do
        ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity String
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
P.manyTill ParsecT Void Text Identity Char
forall e s (m :: * -> *). MonadParsec e s m => m (Token s)
P.anySingle ParsecT Void Text Identity Text
"your answer is" ParsecT Void Text Identity String
-> ParsecT Void Text Identity () -> ParsecT Void Text Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void Text Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
P.space1
        Maybe String
-> (Token Text -> Bool) -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Maybe String -> (Token s -> Bool) -> m (Tokens s)
P.takeWhile1P (String -> Maybe String
forall a. a -> Maybe a
Just String
"dot") (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'.')
      ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity String
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
P.manyTill ParsecT Void Text Identity Char
forall e s (m :: * -> *). MonadParsec e s m => m (Token s)
P.anySingle (Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
(MonadParsec e s m, FoldCase (Tokens s)) =>
Tokens s -> m (Tokens s)
P.string' Tokens Text
"wait") ParsecT Void Text Identity String
-> ParsecT Void Text Identity () -> ParsecT Void Text Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void Text Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
P.space1
      Int
waitAmt <- (Int
1 Int
-> ParsecT Void Text Identity Text
-> ParsecT Void Text Identity Int
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
(MonadParsec e s m, FoldCase (Tokens s)) =>
Tokens s -> m (Tokens s)
P.string' Tokens Text
"one") ParsecT Void Text Identity Int
-> ParsecT Void Text Identity Int -> ParsecT Void Text Identity Int
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Int
forall e s (m :: * -> *) a.
(MonadParsec e s m, Token s ~ Char, Num a) =>
m a
P.decimal
      SubmitRes -> Parsec Void Text SubmitRes
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SubmitRes -> Parsec Void Text SubmitRes)
-> SubmitRes -> Parsec Void Text SubmitRes
forall a b. (a -> b) -> a -> b
$ Int -> Maybe String -> SubmitRes
SubIncorrect (Int
waitAmt Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
60) (Text -> String
T.unpack (Text -> String) -> Maybe Text -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
hint)
    parseWait :: Parsec Void Text SubmitRes
parseWait = do
      String
_ <- ParsecT Void Text Identity Char
-> ParsecT Void Text Identity (Tokens Text)
-> ParsecT Void Text Identity String
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
P.manyTill ParsecT Void Text Identity Char
forall e s (m :: * -> *). MonadParsec e s m => m (Token s)
P.anySingle (Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
(MonadParsec e s m, FoldCase (Tokens s)) =>
Tokens s -> m (Tokens s)
P.string' Tokens Text
"an answer too recently") ParsecT Void Text Identity String
-> String -> ParsecT Void Text Identity String
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
P.<?> String
"An answer too recently"
      ParsecT Void Text Identity Char -> ParsecT Void Text Identity ()
forall (m :: * -> *) a. MonadPlus m => m a -> m ()
P.skipMany ((Token Text -> Bool) -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
(Token s -> Bool) -> m (Token s)
P.satisfy (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isDigit))
      Maybe Int
m <- ParsecT Void Text Identity Int
-> ParsecT Void Text Identity (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ParsecT Void Text Identity Int
 -> ParsecT Void Text Identity (Maybe Int))
-> (ParsecT Void Text Identity Int
    -> ParsecT Void Text Identity Int)
-> ParsecT Void Text Identity Int
-> ParsecT Void Text Identity (Maybe Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ParsecT Void Text Identity Int
-> String -> ParsecT Void Text Identity Int
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
P.<?> String
"Delay minutes") (ParsecT Void Text Identity Int -> ParsecT Void Text Identity Int)
-> (ParsecT Void Text Identity Int
    -> ParsecT Void Text Identity Int)
-> ParsecT Void Text Identity Int
-> ParsecT Void Text Identity Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT Void Text Identity Int -> ParsecT Void Text Identity Int
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
P.try (ParsecT Void Text Identity Int
 -> ParsecT Void Text Identity (Maybe Int))
-> ParsecT Void Text Identity Int
-> ParsecT Void Text Identity (Maybe Int)
forall a b. (a -> b) -> a -> b
$
              ParsecT Void Text Identity Int
forall e s (m :: * -> *) a.
(MonadParsec e s m, Token s ~ Char, Num a) =>
m a
P.decimal ParsecT Void Text Identity Int
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Int
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
P.char Char
Token Text
'm' ParsecT Void Text Identity Int
-> ParsecT Void Text Identity () -> ParsecT Void Text Identity Int
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Void Text Identity ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
P.space1
      Int
s <- ParsecT Void Text Identity Int
forall e s (m :: * -> *) a.
(MonadParsec e s m, Token s ~ Char, Num a) =>
m a
P.decimal ParsecT Void Text Identity Int
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Int
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
P.char Char
Token Text
's' ParsecT Void Text Identity Int
-> String -> ParsecT Void Text Identity Int
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
P.<?> String
"Delay seconds"
      SubmitRes -> Parsec Void Text SubmitRes
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SubmitRes -> Parsec Void Text SubmitRes)
-> (Int -> SubmitRes) -> Int -> Parsec Void Text SubmitRes
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> SubmitRes
SubWait (Int -> Parsec Void Text SubmitRes)
-> Int -> Parsec Void Text SubmitRes
forall a b. (a -> b) -> a -> b
$ Int -> (Int -> Int) -> Maybe Int -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
60) Maybe Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
s
    parseInvalid :: Parsec Void Text SubmitRes
parseInvalid = SubmitRes
SubInvalid SubmitRes
-> ParsecT Void Text Identity [Token Text]
-> Parsec Void Text SubmitRes
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT Void Text Identity (Token Text)
-> ParsecT Void Text Identity (Tokens Text)
-> ParsecT Void Text Identity [Token Text]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
P.manyTill ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *). MonadParsec e s m => m (Token s)
P.anySingle (Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
(MonadParsec e s m, FoldCase (Tokens s)) =>
Tokens s -> m (Tokens s)
P.string' Tokens Text
"solving the right level")

-- | Pretty-print a 'SubmitRes'
showSubmitRes :: SubmitRes -> String
showSubmitRes :: SubmitRes -> String
showSubmitRes = \case
    SubCorrect Maybe Integer
Nothing    -> String
"Correct"
    SubCorrect (Just Integer
r)   -> String -> Integer -> String
forall r. PrintfType r => String -> r
printf String
"Correct (Rank %d)" Integer
r
    SubIncorrect Int
i Maybe String
Nothing  -> String -> Int -> String
forall r. PrintfType r => String -> r
printf String
"Incorrect (%d minute wait)" (Int
i Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
60)
    SubIncorrect Int
i (Just String
h) -> String -> String -> Int -> String
forall r. PrintfType r => String -> r
printf String
"Incorrect (%s) (%d minute wait)" String
h (Int
i Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
60)
    SubWait Int
i             -> let (Int
m,Int
s) = Int
i Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
`divMod` Int
60
                             in   String -> Int -> Int -> String
forall r. PrintfType r => String -> r
printf String
"Wait (%d min %d sec wait)"  Int
m Int
s
    SubmitRes
SubInvalid            -> String
"Invalid"
    SubUnknown String
r          -> String -> ShowS
forall r. PrintfType r => String -> r
printf String
"Unknown (%s)" String
r

-- | Convert a @'Finite' 25@ day into a day integer (1 - 25).  Inverse of
-- 'mkDay'.
dayInt :: Day -> Integer
dayInt :: Day -> Integer
dayInt = (Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1) (Integer -> Integer) -> (Day -> Integer) -> Day -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Finite 25 -> Integer
forall (n :: Nat). Finite n -> Integer
getFinite (Finite 25 -> Integer) -> (Day -> Finite 25) -> Day -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Finite 25
dayFinite

-- | Convert a 'Part' to an 'Int'.
partInt :: Part -> Int
partInt :: Part -> Int
partInt Part
Part1 = Int
1
partInt Part
Part2 = Int
2

-- | Construct a 'Day' from a day integer (1 - 25).  If input is out of
-- range, 'Nothing' is returned.  See 'mkDay_' for an unsafe version useful
-- for literals.
--
-- Inverse of 'dayInt'.
mkDay :: Integer -> Maybe Day
mkDay :: Integer -> Maybe Day
mkDay = (Finite 25 -> Day) -> Maybe (Finite 25) -> Maybe Day
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Finite 25 -> Day
Day (Maybe (Finite 25) -> Maybe Day)
-> (Integer -> Maybe (Finite 25)) -> Integer -> Maybe Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Maybe (Finite 25)
forall (n :: Nat). KnownNat n => Integer -> Maybe (Finite n)
packFinite (Integer -> Maybe (Finite 25))
-> (Integer -> Integer) -> Integer -> Maybe (Finite 25)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
subtract Integer
1

-- | Construct a @'Finite' 25@ (the type of a Day) from a day
-- integer (1 - 25).  Is undefined if input is out of range.  Can be useful
-- for compile-time literals, like @'mkDay_' 4@
--
-- Inverse of 'dayInt'.
mkDay_ :: Integer -> Day
mkDay_ :: Integer -> Day
mkDay_ = Day -> Maybe Day -> Day
forall a. a -> Maybe a -> a
fromMaybe Day
forall a. a
e (Maybe Day -> Day) -> (Integer -> Maybe Day) -> Integer -> Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Maybe Day
mkDay
  where
    e :: a
e = String -> a
forall a. String -> a
errorWithoutStackTrace String
"Advent.mkDay_: Date out of range (1 - 25)"

-- | This is a @Prism' 'Integer' 'Day'@ , to treat an 'Integer' as if it
-- were a 'Day'.
--
-- @since 0.2.4.0
_DayInt :: (Choice p, Applicative f) => p Day (f Day) -> p Integer (f Integer)
_DayInt :: p Day (f Day) -> p Integer (f Integer)
_DayInt = (Integer -> Either Integer Day)
-> (Either Integer (f Day) -> f Integer)
-> p (Either Integer Day) (Either Integer (f Day))
-> p Integer (f Integer)
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap Integer -> Either Integer Day
a Either Integer (f Day) -> f Integer
b (p (Either Integer Day) (Either Integer (f Day))
 -> p Integer (f Integer))
-> (p Day (f Day)
    -> p (Either Integer Day) (Either Integer (f Day)))
-> p Day (f Day)
-> p Integer (f Integer)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p Day (f Day) -> p (Either Integer Day) (Either Integer (f Day))
forall (p :: * -> * -> *) a b c.
Choice p =>
p a b -> p (Either c a) (Either c b)
right'
  where
    a :: Integer -> Either Integer Day
a Integer
i = Either Integer Day
-> (Day -> Either Integer Day) -> Maybe Day -> Either Integer Day
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Integer -> Either Integer Day
forall a b. a -> Either a b
Left Integer
i) Day -> Either Integer Day
forall a b. b -> Either a b
Right (Maybe Day -> Either Integer Day)
-> (Integer -> Maybe Day) -> Integer -> Either Integer Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Maybe Day
mkDay (Integer -> Either Integer Day) -> Integer -> Either Integer Day
forall a b. (a -> b) -> a -> b
$ Integer
i
    b :: Either Integer (f Day) -> f Integer
b   = (Integer -> f Integer)
-> (f Day -> f Integer) -> Either Integer (f Day) -> f Integer
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Integer -> f Integer
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Day -> Integer) -> f Day -> f Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Day -> Integer
dayInt)

-- | Pattern synonym allowing you to match on an 'Integer' as if it were
-- a 'Day':
--
-- @
-- case myInt of
--   DayInt d -> ...
--   _        -> ...
-- @
--
-- Will fail if the integer is out of bounds (outside of 1-25)
--
-- @since 0.2.4.0
pattern DayInt :: Day -> Integer
pattern $bDayInt :: Day -> Integer
$mDayInt :: forall r. Integer -> (Day -> r) -> (Void# -> r) -> r
DayInt d <- (mkDay->Just d)
  where
    DayInt Day
d = Day -> Integer
dayInt Day
d

-- | A character associated with a given part.  'Part1' is associated with
-- @\'a\'@, and 'Part2' is associated with @\'b\'@
partChar :: Part -> Char
partChar :: Part -> Char
partChar Part
Part1 = Char
'a'
partChar Part
Part2 = Char
'b'

-- | Check if a 'DailyLeaderboard' is filled up or not.
--
-- @since 0.2.4.0
fullDailyBoard
    :: DailyLeaderboard
    -> Bool
fullDailyBoard :: DailyLeaderboard -> Bool
fullDailyBoard DLB{Map Rank DailyLeaderboardMember
dlbStar2 :: Map Rank DailyLeaderboardMember
dlbStar1 :: Map Rank DailyLeaderboardMember
dlbStar2 :: DailyLeaderboard -> Map Rank DailyLeaderboardMember
dlbStar1 :: DailyLeaderboard -> Map Rank DailyLeaderboardMember
..} = (Map Rank DailyLeaderboardMember -> Int
forall k a. Map k a -> Int
M.size Map Rank DailyLeaderboardMember
dlbStar1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Map Rank DailyLeaderboardMember -> Int
forall k a. Map k a -> Int
M.size Map Rank DailyLeaderboardMember
dlbStar2) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
200

-- | Prompt release time.
--
-- Changed from 'UTCTime' to 'ZonedTime' in v0.2.7.0.  To use as
-- a 'UTCTime', use 'zonedTimeToUTC'.
challengeReleaseTime
    :: Integer              -- ^ year
    -> Day                  -- ^ day
    -> ZonedTime
challengeReleaseTime :: Integer -> Day -> ZonedTime
challengeReleaseTime Integer
y Day
d = ZonedTime :: LocalTime -> TimeZone -> ZonedTime
ZonedTime
    { zonedTimeToLocalTime :: LocalTime
zonedTimeToLocalTime = LocalTime :: Day -> TimeOfDay -> LocalTime
LocalTime
        { localDay :: Day
localDay       = Integer -> Int -> Int -> Day
fromGregorian Integer
y Int
12 (Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Day -> Integer
dayInt Day
d))
        , localTimeOfDay :: TimeOfDay
localTimeOfDay = TimeOfDay
midnight
        }
    , zonedTimeZone :: TimeZone
zonedTimeZone = String -> TimeZone
forall a. Read a => String -> a
read String
"EST"
    }