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

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)
]