Represents both how to encode encodesFrom
into a JSON object
and decode a JSON object into decodesTo
.
This is similar to JsonMapping
, but it allows a pipeline-style API for building up mappings
(see object
, with
, static
).
Notably this is used with DesktopApp.program
to specify how to save and load data.
When used in that way, the encodesFrom
type will be your program's model,
and the decodesTo
type will be your program's msg (which will be produced when data is loaded).
Also of note: when encodesFrom
and decodesTo
are the same type it specifies a two-way mapping to and from JSON
(and can then be turned into a JsonMapping
with fromObjectMapping
).
object : decodesTo -> ObjectMapping encodesFrom decodesTo
Creates a trivial ObjectMapping
.
This, along with with
, static
make up a pipeline-style API
which can be used like this:
import DesktopApp.JsonMapping exposing (ObjectMapping, int, object, with)
type alias MyData =
{ total : Int
, count : Int
}
myObjectMapping : ObjectMapping MyData MyData
myObjectMapping =
object MyData
|> with "total" .total int
|> with "count" .count int
with : String -> (encodesFrom -> a) -> JsonMapping a -> ObjectMapping encodesFrom (a -> decodesTo) -> ObjectMapping encodesFrom decodesTo
Adds a field to an object. It will be represented in both your Elm model and in the JSON.
static : String -> a -> JsonMapping a -> ObjectMapping encodesFrom decodesTo -> ObjectMapping encodesFrom decodesTo
Adds a static field to an object. The field will not be represented in your Elm model, but this exact field name and value will be added to the encoded JSON.
mapObjectDecoding : (a -> b) -> ObjectMapping encodesFrom a -> ObjectMapping encodesFrom b
Transforms the type that an ObjectMapping
decodes.
mapObjectEncoding : (b -> a) -> ObjectMapping a decodesTo -> ObjectMapping b decodesTo
Transforms the type that an ObjectMapping
encodes.
customObject : (encodesFrom -> List ( String, Json.Encode.Value )) -> Json.Decode.Decoder decodesTo -> ObjectMapping encodesFrom decodesTo
If you have some data type for which the object
and with
API doesn't meet your needs,
you can use customObject
to create an ObjectMapping
for any type that you can write an encoder and decoder for.
ObjectMapping
sNormally you will just pass your ObjectMapping
to DesktopApp.program
,
but the following functions are available if you want to manually make use of an ObjectMapping
for other purposes.
encodeString : ObjectMapping encodesFrom decodesTo -> encodesFrom -> String
Encodes a given encodesFrom
value with the given ObjectMapping (into a JSON string).
encodeValue : ObjectMapping encodesFrom decodesTo -> encodesFrom -> Json.Encode.Value
Encodes a given encodesFrom
value with the given ObjectMapping (into a Json.Encode.Value
).
decoder : ObjectMapping encodesFrom decodesTo -> Json.Decode.Decoder decodesTo
Gets the Json.Decode.Decoder
for the given ObjectMapping
.
Represents how to encode a
to and from JSON.
int : JsonMapping Basics.Int
Maps an Elm Int
to and from JSON.
string : JsonMapping String
Maps an Elm String
to and from JSON.
bool : JsonMapping Basics.Bool
Maps an Elm Bool
to and from JSON.
maybe : JsonMapping a -> JsonMapping (Maybe a)
Maps an Elm Maybe
to and from JSON.
Nothing
will map to null
,
and Just a
will use the given mapping for a
.
import DesktopApp.JsonMapping exposing (maybe, int, encode, decoder)
import Json.Decode exposing (decodeString)
encode (maybe int) (Just 7) --> "7"
encode (maybe int) Nothing --> "null"
decodeString (decoder (maybe string)) "\"hi\"" --> Just "hi"
decodeString (decoder (maybe string)) "null" --> Nothing
list : JsonMapping a -> JsonMapping (List a)
Maps an Elm List
to and from a JSON array.
custom : (a -> Json.Encode.Value) -> Json.Decode.Decoder a -> JsonMapping a
Creates a JsonMapping
that uses the given Elm JSON encoder and decoder
fromObjectMapping : ObjectMapping a a -> JsonMapping a
Creates a JsonMapping
from an ObjectMapping
.
This allows you to create JsonMapping
s that can then be used as nested fields within other ObjectMappings
.
import DesktopApp.JsonMapping exposing (fromObjectMapping, int, object, string, with)
type alias MyData =
{ name : String
, admin : Bool
}
myDataMapping : JsonMapping MyData
myDataMapping =
object MyData
|> with "name" .name string
|> with "admin" .admin bool
|> fromObjectMapping
map : (a -> b) -> (b -> a) -> JsonMapping a -> JsonMapping b
Transforms a JsonMapping
. This requires functions for transforming in each direction
so that both encoding and decoding can be handled.
customType : List (VariantDecoder a) -> (a -> VariantEncoder) -> ObjectMapping a a
Maps an Elm custom type (sometimes also called a "union type", "tagged union", or "ADT") to and from a JSON object.
VariantDecoder
s and VariantEncoder
s are created using the variant*
functions (see the example below).
This function returns an ObjectMapping
instead of a JsonMapping
so that it is possible to have a custom type as the top-level of your persisted data when using DesktopApp.program
.
If you need a JsonMapping
, you can use this with fromObjectMapping
(as shown in the example).
As this example shows, creating a mapping for your custom type requires the following:
let
block, create Variant
s for each variant of your custom type using the variant*
funtionscustomType
, pass a list containing the .decode
from all of your variantscustomType
, pass a function that destructures a value of your type and returns the corresponding variant's encoder with the destructured parameter values applied.Example:
import DesktopApp.JsonMapping exposing (JsonMapping, bool, customType, fromObjectMapping, int, string, variant0, variant1, variant2)
type MyType
= NotAuthorized
| Guest Bool String
| Employee Int
myTypeMapping : JsonMapping MyType
myTypeMapping =
let
notAuthorized =
variant0
"NotAuthorized"
NotAuthorized
guest =
variant2
"Guest"
Guest
( "is_vip", bool )
( "name", string )
employee =
variant1
"Employee"
Employee
( "employee_id", int )
in
customType
[ notAuthorized.decode
, guest.decode
, employeed.decode
]
(\x ->
case x of
NotAuthorized ->
notAuthorized.encode
Guest isVip name ->
guest.encode isVip name
Employee id ->
employeed.encode id
)
|> fromObjectMapping
encodeString myTypeMapping NotAuthorized
--> """{"$":"NotAuthorized"}"""
encodeString myTypeMapping (Guest True "Kai")
--> """{"$":"Guest","is\_vip":true,"name":"Kai"}"""
encodeString myTypeMapping (Employee 24601)
--> """{"$":"Employee","employee\_id":24601}"""
{ decode : VariantDecoder decodesTo
, encode : encoder
}
Represents how to map an Elm custom type variant (sometimes also called a "tag", "contructor", or "enum value") to and from a JSON object.
This is different from a JsonMapping
because it carries with it information about the name of the variant
and does some tricks with the type system to make the customType
API as nice as possible.
Normally you will not need to reference this type directly. See the example for customType
.
Represents how to encode an Elm custom type variant to a JSON object.
Normally you will not need to reference this type directly. See the example for customType
.
Represents how to decode an Elm custom type variant from a JSON object.
Normally you will not need to reference this type directly. See the example for customType
.
variant0 : String -> decodesTo -> Variant decodesTo VariantEncoder
Creates a VariantEncoder
and VariantDecoder
for an Elm custom type variant that takes no parameters.
See customType
for an example of how to use the variant*
functions.
variant1 : String -> (a -> decodesTo) -> ( String, JsonMapping a ) -> Variant decodesTo (a -> VariantEncoder)
Creates a VariantEncoder
and VariantDecoder
for an Elm custom type variant that takes one parameter.
See customType
for an example of how to use the variant*
functions.
variant2 : String -> (a -> b -> decodesTo) -> ( String, JsonMapping a ) -> ( String, JsonMapping b ) -> Variant decodesTo (a -> b -> VariantEncoder)
Creates a VariantEncoder
and VariantDecoder
for an Elm custom type variant that takes two parameters.
See customType
for an example of how to use the variant*
functions.
variant3 : String -> (a -> b -> c -> decodesTo) -> ( String, JsonMapping a ) -> ( String, JsonMapping b ) -> ( String, JsonMapping c ) -> Variant decodesTo (a -> b -> c -> VariantEncoder)
Creates a VariantEncoder
and VariantDecoder
for an Elm custom type variant that takes three parameters.
See customType
for an example of how to use the variant*
functions.
variant4 : String -> (a -> b -> c -> d -> decodesTo) -> ( String, JsonMapping a ) -> ( String, JsonMapping b ) -> ( String, JsonMapping c ) -> ( String, JsonMapping d ) -> Variant decodesTo (a -> b -> c -> d -> VariantEncoder)
Creates a VariantEncoder
and VariantDecoder
for an Elm custom type variant that takes four parameters.
See customType
for an example of how to use the variant*
functions.
variant5 : String -> (a -> b -> c -> d -> e -> decodesTo) -> ( String, JsonMapping a ) -> ( String, JsonMapping b ) -> ( String, JsonMapping c ) -> ( String, JsonMapping d ) -> ( String, JsonMapping e ) -> Variant decodesTo (a -> b -> c -> d -> e -> VariantEncoder)
Creates a VariantEncoder
and VariantDecoder
for an Elm custom type variant that takes five parameters.
See customType
for an example of how to use the variant*
functions.