فهرست منبع

Encode data ready for indexeddb

Cadel Watson 1 سال پیش
والد
کامیت
6073ce4c02
5فایلهای تغییر یافته به همراه263 افزوده شده و 2 حذف شده
  1. 5 0
      js/app.js
  2. 1 0
      src/Card.elm
  3. 132 1
      src/Database.elm
  4. 3 1
      src/Main.elm
  5. 122 0
      tests/TestDatabase.elm

+ 5 - 0
js/app.js

@@ -53,5 +53,10 @@ openDBRequest.onsuccess = (event) => {
             app.ports.receiveDoesSetHaveLocalData.send(JSON.stringify(data));
         })
     });
+
+    app.ports.sendSaveLocalData.subscribe((setData) => {
+        console.log("SAVE");
+        console.log(setData);
+    })
 };
 

+ 1 - 0
src/Card.elm

@@ -61,6 +61,7 @@ type alias CardDetails =
     , power : Maybe Power
     , toughness : Maybe Power
     , colors : List ManaColor
+    , rawManaCost : String
     , manaCost : Maybe (List ManaCost)
     , imageUrl : String
     }

+ 132 - 1
src/Database.elm

@@ -1,9 +1,10 @@
-module Database exposing (Database, decode, decoder, get, getAll)
+module Database exposing (Database, decode, decoder, encode, fromCardData, 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 Json.Encode as Encode
 import Tuple exposing (pair)
 
 
@@ -11,6 +12,13 @@ type Database
     = Database (Dict String CardData)
 
 
+fromCardData : List CardData -> Database
+fromCardData cards =
+    List.map (\card -> ( card.details.name, card )) cards
+        |> Dict.fromList
+        |> Database
+
+
 get : String -> Database -> Maybe CardData
 get name (Database db) =
     Dict.get name db
@@ -40,6 +48,24 @@ decoder =
         )
 
 
+databaseToDict : Database -> Dict String CardData
+databaseToDict (Database db) =
+    db
+
+
+encode : ( String, Database ) -> Encode.Value
+encode ( setCode, Database db ) =
+    Encode.object
+        [ ( "code", Encode.string setCode )
+        , ( "data"
+          , Encode.object
+                [ ( "ratings", Encode.list encodeCardPerformance (Dict.values db) )
+                , ( "cards", Encode.list encodeCardDetails (Dict.values db) )
+                ]
+          )
+        ]
+
+
 createDatabase : Dict String CardPerformanceData -> Dict String CardDetails -> Database
 createDatabase performanceData detailsData =
     Dict.merge
@@ -64,6 +90,28 @@ decodeSetData =
         |> Decode.map Dict.fromList
 
 
+encodeCardPerformance : CardData -> Encode.Value
+encodeCardPerformance d =
+    Encode.object
+        [ ( "Name", Encode.string d.details.name )
+        , ( "# Seen", encodeIntString d.performance.totalTimesSeen )
+        , ( "# Picked", encodeIntString d.performance.totalTimesPicked )
+        , ( "ATA", encodeMaybeFloatString d.performance.averagePickPosition )
+        , ( "ALSA", encodeMaybeFloatString d.performance.averageSeenPosition )
+        , ( "GIH WR", encodeMaybePercentageString d.performance.gameInHandWinRate )
+        , ( "IWD"
+          , Encode.string
+                (case d.performance.improvementWhenDrawn of
+                    Just i ->
+                        String.fromFloat i ++ "pp"
+
+                    Nothing ->
+                        ""
+                )
+          )
+        ]
+
+
 decodeCardPerformance : Decoder ( String, CardPerformanceData )
 decodeCardPerformance =
     Decode.map2 pair
@@ -96,6 +144,11 @@ decodeImprovementWhenDrawn =
             )
 
 
+encodeIntString : Int -> Encode.Value
+encodeIntString i =
+    Encode.string (String.fromInt i)
+
+
 decodeIntString : Decoder Int
 decodeIntString =
     Decode.string
@@ -110,6 +163,16 @@ decodeIntString =
             )
 
 
+encodeMaybeFloatString : Maybe Float -> Encode.Value
+encodeMaybeFloatString m =
+    case m of
+        Just f ->
+            Encode.string (String.fromFloat f)
+
+        Nothing ->
+            Encode.string ""
+
+
 decodeMaybeFloatString : Decoder (Maybe Float)
 decodeMaybeFloatString =
     Decode.string
@@ -128,6 +191,16 @@ decodeMaybeFloatString =
             )
 
 
+encodeMaybePercentageString : Maybe Float -> Encode.Value
+encodeMaybePercentageString m =
+    case m of
+        Just f ->
+            Encode.string (String.fromFloat (f * 100) ++ "%")
+
+        Nothing ->
+            Encode.string ""
+
+
 decodeMaybePercentageString : Decoder (Maybe Float)
 decodeMaybePercentageString =
     Decode.string
@@ -146,6 +219,28 @@ decodeMaybePercentageString =
             )
 
 
+encodeCardDetails : CardData -> Encode.Value
+encodeCardDetails card =
+    Encode.object
+        [ ( "name", Encode.string card.details.name )
+        , ( "cmc", Encode.int card.details.cmc )
+        , ( "type_line", Encode.string card.details.typeLine )
+        , ( "oracle_text"
+          , case card.details.oracleText of
+                Just t ->
+                    Encode.string t
+
+                Nothing ->
+                    Encode.null
+          )
+        , ( "power", encodePower card.details.power )
+        , ( "toughness", encodePower card.details.toughness )
+        , ( "colors", Encode.list encodeManaColor card.details.colors )
+        , ( "mana_cost", Encode.string card.details.rawManaCost )
+        , ( "image_uris", Encode.object [ ( "large", Encode.string card.details.imageUrl ) ] )
+        ]
+
+
 decodeCardDetails : Decoder ( String, CardDetails )
 decodeCardDetails =
     Decode.map2 pair
@@ -159,6 +254,7 @@ decodeCardDetails =
             |> optional "power" (Decode.nullable decodePower) Nothing
             |> optional "toughness" (Decode.nullable decodePower) Nothing
             |> required "colors" (Decode.list decodeManaColor)
+            |> required "mana_cost" Decode.string
             |> required "mana_cost"
                 (Decode.string
                     |> Decode.andThen
@@ -175,6 +271,19 @@ decodeCardDetails =
         )
 
 
+encodePower : Maybe Power -> Encode.Value
+encodePower p =
+    case p of
+        Just (ConstantPower i) ->
+            Encode.string (String.fromInt i)
+
+        Just VariablePower ->
+            Encode.string "*"
+
+        Nothing ->
+            Encode.null
+
+
 decodePower : Decoder Power
 decodePower =
     Decode.string
@@ -193,6 +302,28 @@ decodePower =
             )
 
 
+encodeManaColor : ManaColor -> Encode.Value
+encodeManaColor c =
+    case c of
+        Red ->
+            Encode.string "R"
+
+        Blue ->
+            Encode.string "U"
+
+        Green ->
+            Encode.string "G"
+
+        White ->
+            Encode.string "W"
+
+        Black ->
+            Encode.string "B"
+
+        Colorless ->
+            Encode.string "C"
+
+
 decodeManaColor : Decoder ManaColor
 decodeManaColor =
     Decode.string

+ 3 - 1
src/Main.elm

@@ -207,7 +207,9 @@ update msg model =
                     )
 
                 IOGotSetData (Ok ( setCode, Just database )) ->
-                    ( ChooseSet { mdl | sets = Maybe.map (Dict.insert setCode (HasLocalData database)) mdl.sets }, Cmd.none )
+                    ( ChooseSet { mdl | sets = Maybe.map (Dict.insert setCode (HasLocalData database)) mdl.sets }
+                    , sendSaveLocalData (Database.encode ( setCode, database ))
+                    )
 
                 IOGotSetData (Err e) ->
                     ( Error { error = "Error fetching remote set data (" ++ e ++ ")" }, Cmd.none )

+ 122 - 0
tests/TestDatabase.elm

@@ -0,0 +1,122 @@
+module TestDatabase exposing (..)
+
+import Card exposing (CardData, CardDetails, CardPerformanceData, CardType(..), ManaColor(..), ManaCost(..), Power(..))
+import Database exposing (Database)
+import Expect
+import Fuzz exposing (Fuzzer)
+import Json.Decode as Decode
+import Json.Encode as Encode
+import Test exposing (Test, describe, fuzz)
+
+
+niceFloat : Fuzzer Float
+niceFloat =
+    Fuzz.floatRange 0 100
+
+
+fuzzDatabase : Fuzzer Database
+fuzzDatabase =
+    Fuzz.listOfLengthBetween 1 2 fuzzCardData
+        |> Fuzz.map Database.fromCardData
+
+
+fuzzCardData : Fuzzer CardData
+fuzzCardData =
+    Fuzz.string
+        |> Fuzz.andThen
+            (\cardName ->
+                Fuzz.constant CardData
+                    |> Fuzz.andMap (fuzzCardDetails cardName)
+                    |> Fuzz.andMap fuzzCardPerformance
+            )
+
+
+fuzzCardPerformance : Fuzzer CardPerformanceData
+fuzzCardPerformance =
+    Fuzz.constant CardPerformanceData
+        |> Fuzz.andMap Fuzz.int
+        |> Fuzz.andMap Fuzz.int
+        |> Fuzz.andMap (Fuzz.maybe niceFloat)
+        |> Fuzz.andMap (Fuzz.maybe niceFloat)
+        |> Fuzz.andMap (Fuzz.maybe (Fuzz.constant 0.5))
+        |> Fuzz.andMap (Fuzz.maybe niceFloat)
+
+
+fuzzCardDetails : String -> Fuzzer CardDetails
+fuzzCardDetails name =
+    Fuzz.constant (CardDetails name)
+        |> Fuzz.andMap Fuzz.int
+        |> Fuzz.andMap (Fuzz.constant Creature)
+        |> Fuzz.andMap (Fuzz.constant "Creature // Pirate")
+        |> Fuzz.andMap (Fuzz.maybe Fuzz.string)
+        |> Fuzz.andMap (Fuzz.maybe fuzzPower)
+        |> Fuzz.andMap (Fuzz.maybe fuzzPower)
+        |> Fuzz.andMap (Fuzz.list fuzzManaColor)
+        |> Fuzz.andMap (Fuzz.constant "{X}{R}")
+        |> Fuzz.andMap (Fuzz.constant (Just [ X, Color Red ]))
+        |> Fuzz.andMap Fuzz.string
+
+
+fuzzCardType : Fuzzer CardType
+fuzzCardType =
+    Fuzz.oneOfValues
+        [ Creature
+        , Instant
+        , Sorcery
+        , Enchantment
+        , Artifact
+        , Planeswalker
+        , Land
+        , Other
+        ]
+
+
+fuzzPower : Fuzzer Power
+fuzzPower =
+    Fuzz.oneOf
+        [ Fuzz.constant VariablePower
+        , Fuzz.int |> Fuzz.map ConstantPower
+        ]
+
+
+fuzzManaColor : Fuzzer ManaColor
+fuzzManaColor =
+    Fuzz.oneOfValues
+        [ Red
+        , Green
+        , Blue
+        , White
+        , Black
+        , Colorless
+        ]
+
+
+fuzzManaCost : Fuzzer ManaCost
+fuzzManaCost =
+    Fuzz.oneOf
+        [ Fuzz.constant X
+        , Fuzz.constant Y
+        , Fuzz.constant Tap
+        , Fuzz.constant Pay
+        , Fuzz.int |> Fuzz.map AnyColor
+        , fuzzManaColor |> Fuzz.map Color
+        , fuzzManaColor |> Fuzz.map ColorPay
+        , fuzzManaColor |> Fuzz.map TwoOrColor
+        , Fuzz.map2 Hybrid fuzzManaColor fuzzManaColor
+        , Fuzz.map2 HybridPay fuzzManaColor fuzzManaColor
+        ]
+
+
+suite : Test
+suite =
+    describe "Database"
+        [ fuzz fuzzDatabase "encoder / decoder round trip" <|
+            \database ->
+                let
+                    roundTrip =
+                        Database.encode ( "mkm", database )
+                            |> Encode.encode 0
+                            |> Decode.decodeString Database.decoder
+                in
+                Expect.equal roundTrip (Ok ( "mkm", Just database ))
+        ]