| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- module Database exposing (Database, decode, get, getAll)
- import Card exposing (CardData, CardDetails, CardPerformanceData, CardType(..), ManaColor(..), Power(..), parseManaCost)
- import Dict exposing (Dict)
- import Json.Decode as Decode exposing (Decoder, decodeString)
- import Json.Decode.Pipeline exposing (optional, required)
- import Tuple exposing (pair)
- type Database
- = Database (Dict String CardData)
- get : String -> Database -> Maybe CardData
- get name (Database db) =
- Dict.get name db
- getAll : Database -> List CardData
- getAll (Database db) =
- Dict.values db
- decode : String -> Result String ( String, Maybe Database )
- decode setData =
- let
- decoder : Decoder ( String, Maybe Database )
- decoder =
- Decode.map2 pair
- (Decode.field "code" Decode.string)
- (Decode.field "data"
- (Decode.nullable
- (Decode.map2 createDatabase
- (Decode.field "ratings" decodePerformanceData)
- (Decode.field "cards" decodeSetData)
- )
- )
- )
- in
- decodeString decoder setData |> Result.mapError Decode.errorToString
- createDatabase : Dict String CardPerformanceData -> Dict String CardDetails -> Database
- createDatabase performanceData detailsData =
- Dict.merge
- (\_ _ cardData -> cardData)
- (\name performance details -> Dict.insert name (CardData details performance))
- (\_ _ cardData -> cardData)
- performanceData
- detailsData
- Dict.empty
- |> Database
- decodePerformanceData : Decoder (Dict String CardPerformanceData)
- decodePerformanceData =
- Decode.list decodeCardPerformance
- |> Decode.map Dict.fromList
- |> Decode.map (Debug.log "perf")
- decodeSetData : Decoder (Dict String CardDetails)
- decodeSetData =
- Decode.list decodeCardDetails
- |> Decode.map Dict.fromList
- decodeCardPerformance : Decoder ( String, CardPerformanceData )
- decodeCardPerformance =
- Decode.map2 pair
- (Decode.field "Name" Decode.string)
- (Decode.succeed CardPerformanceData
- |> required "# Seen" decodeIntString
- |> required "# Picked" decodeIntString
- |> required "ATA" decodeMaybeFloatString
- |> required "ALSA" decodeMaybeFloatString
- |> required "GIH WR" decodeMaybePercentageString
- |> required "IWD" decodeImprovementWhenDrawn
- )
- decodeImprovementWhenDrawn : Decoder (Maybe Float)
- decodeImprovementWhenDrawn =
- Decode.string
- |> Decode.andThen
- (\s ->
- if s == "" then
- Decode.succeed Nothing
- else
- case String.toFloat (String.replace "pp" "" s) of
- Just i ->
- Decode.succeed (Just i)
- Nothing ->
- Decode.succeed Nothing
- )
- decodeIntString : Decoder Int
- decodeIntString =
- Decode.string
- |> Decode.andThen
- (\s ->
- case String.toInt s of
- Just i ->
- Decode.succeed i
- Nothing ->
- Decode.fail "Invalid integer"
- )
- decodeMaybeFloatString : Decoder (Maybe Float)
- decodeMaybeFloatString =
- Decode.string
- |> Decode.andThen
- (\s ->
- if s == "" then
- Decode.succeed Nothing
- else
- case String.toFloat s of
- Just i ->
- Decode.succeed (Just i)
- Nothing ->
- Decode.succeed Nothing
- )
- decodeMaybePercentageString : Decoder (Maybe Float)
- decodeMaybePercentageString =
- Decode.string
- |> Decode.andThen
- (\s ->
- if s == "" then
- Decode.succeed Nothing
- else
- case String.toFloat (String.replace "%" "" s) of
- Just i ->
- Decode.succeed (Just (i / 100))
- Nothing ->
- Decode.succeed Nothing
- )
- decodeCardDetails : Decoder ( String, CardDetails )
- decodeCardDetails =
- Decode.map2 pair
- (Decode.field "name" Decode.string)
- (Decode.succeed CardDetails
- |> required "name" Decode.string
- |> required "cmc" Decode.int
- |> required "type_line" decodeCardType
- |> required "type_line" Decode.string
- |> optional "oracle_text" (Decode.nullable Decode.string) Nothing
- |> optional "power" (Decode.nullable decodePower) Nothing
- |> optional "toughness" (Decode.nullable decodePower) Nothing
- |> required "colors" (Decode.list decodeManaColor)
- |> required "mana_cost"
- (Decode.string
- |> Decode.andThen
- (\s ->
- case parseManaCost s of
- Just m ->
- Decode.succeed (Just m)
- Nothing ->
- Decode.succeed Nothing
- )
- )
- |> required "image_uris" (Decode.field "large" Decode.string)
- )
- decodePower : Decoder Power
- decodePower =
- Decode.string
- |> Decode.andThen
- (\s ->
- if s == "*" then
- Decode.succeed VariablePower
- else
- case String.toInt s of
- Just i ->
- Decode.succeed (ConstantPower i)
- Nothing ->
- Decode.fail "Invalid integer"
- )
- decodeManaColor : Decoder ManaColor
- decodeManaColor =
- Decode.string
- |> Decode.andThen
- (\c ->
- case c of
- "R" ->
- Decode.succeed Red
- "U" ->
- Decode.succeed Blue
- "G" ->
- Decode.succeed Green
- "W" ->
- Decode.succeed White
- "B" ->
- Decode.succeed Black
- "C" ->
- Decode.succeed Colorless
- _ ->
- Decode.fail "Invalid mana color"
- )
- decodeCardType : Decoder CardType
- decodeCardType =
- Decode.string
- |> Decode.map
- (\c ->
- if String.contains "Creature" c then
- Creature
- else if String.contains "Instant" c then
- Instant
- else if String.contains "Sorcery" c then
- Sorcery
- else if String.contains "Enchantment" c then
- Enchantment
- else if String.contains "Artifact" c then
- Artifact
- else if String.contains "Planeswalker" c then
- Planeswalker
- else if String.contains "Land" c then
- Land
- else
- Other
- )
|