You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.3 KiB
129 lines
3.3 KiB
module HRInfo exposing ( HRAPI
|
|
, HRInfo
|
|
, HRError
|
|
, decoder
|
|
, encoder
|
|
, statsDecoder
|
|
, strError
|
|
, strExpiry
|
|
)
|
|
|
|
import Json.Decode as D
|
|
import Json.Encode as E
|
|
import Json.Decode.Pipeline exposing (required)
|
|
import Time exposing (Posix, Weekday, Zone)
|
|
|
|
type alias HRAPI = Result HRError (Posix, HRInfo)
|
|
|
|
type HRError
|
|
= NotFound
|
|
| InvalidCode
|
|
| AdminMaintenance
|
|
| ScheduledMaintenance
|
|
| Unknown String
|
|
|
|
type alias HRInfo =
|
|
{ hr : String
|
|
, population : Int
|
|
, engName : String
|
|
, terseName : String
|
|
, province : String
|
|
, terseProv : String
|
|
, last7 : Int
|
|
, last14 : Int
|
|
}
|
|
|
|
translateError : String -> HRError
|
|
translateError errString =
|
|
case errString of
|
|
"not-found" -> NotFound
|
|
"invalid-code" -> InvalidCode
|
|
"admin-maintenance" -> AdminMaintenance
|
|
"scheduled-maintenance" -> ScheduledMaintenance
|
|
any -> Unknown any
|
|
|
|
errorDecoder : D.Decoder HRError
|
|
errorDecoder =
|
|
D.map translateError (D.field "error" D.string)
|
|
|
|
timeDecoder : D.Decoder Posix
|
|
timeDecoder =
|
|
D.map (\ts -> Time.millisToPosix (ts * 1000)) D.int
|
|
|
|
statsDecoder : D.Decoder HRInfo
|
|
statsDecoder =
|
|
D.succeed HRInfo
|
|
|> required "hr" D.string
|
|
|> required "population" D.int
|
|
|> required "hr-full" D.string
|
|
|> required "hr-terse" D.string
|
|
|> required "province" D.string
|
|
|> required "prov-terse" D.string
|
|
|> required "last-7" D.int
|
|
|> required "last-14" D.int
|
|
|
|
apiDecoder : D.Decoder (Posix, HRInfo)
|
|
apiDecoder =
|
|
D.map2 Tuple.pair
|
|
( D.succeed identity
|
|
|> required "expires" timeDecoder
|
|
)
|
|
statsDecoder
|
|
|
|
timeEncoder : Posix -> E.Value
|
|
timeEncoder time =
|
|
Time.toMillis Time.utc time
|
|
|> E.int
|
|
|
|
encoder : HRInfo -> E.Value
|
|
encoder hrInfo =
|
|
E.object
|
|
[ ("hr", E.string hrInfo.hr)
|
|
, ("population", E.int hrInfo.population)
|
|
, ("hr-full", E.string hrInfo.engName)
|
|
, ("hr-terse", E.string hrInfo.terseName)
|
|
, ("province", E.string hrInfo.province)
|
|
, ("prov-terse", E.string hrInfo.terseProv)
|
|
, ("last-7", E.int hrInfo.last7)
|
|
, ("last-14", E.int hrInfo.last14)
|
|
]
|
|
|
|
decoder : D.Decoder HRAPI
|
|
decoder =
|
|
D.oneOf [ D.map Err errorDecoder
|
|
, D.map Ok apiDecoder
|
|
]
|
|
|
|
strError : HRError -> String
|
|
strError err =
|
|
case err of
|
|
NotFound -> "Couldn't find that postal code in my data, try another nearby."
|
|
InvalidCode -> "That doesn't look like valid fnord input, are you messing with validation?"
|
|
AdminMaintenance -> "The database is being worked on, check back later."
|
|
ScheduledMaintenance -> "The database is updating, check back in a few minutes."
|
|
Unknown _ -> "An unknown error occurred."
|
|
|
|
weekdayString : Time.Weekday -> String
|
|
weekdayString wd =
|
|
case wd of
|
|
Time.Mon -> "Mon"
|
|
Time.Tue -> "Tue"
|
|
Time.Wed -> "Wed"
|
|
Time.Thu -> "Thu"
|
|
Time.Fri -> "Fri"
|
|
Time.Sat -> "Sat"
|
|
Time.Sun -> "Sun"
|
|
|
|
|
|
strExpiry : Posix -> Zone -> String
|
|
strExpiry info tz =
|
|
List.foldr (++) ""
|
|
[ String.fromInt (Time.toDay tz info)
|
|
, ","
|
|
, weekdayString (Time.toWeekday tz info)
|
|
, " "
|
|
, String.fromInt (Time.toHour tz info)
|
|
, ":"
|
|
, String.fromInt (Time.toMinute tz info)
|
|
]
|