A Codec a
contain a JSON Decoder a
and the corresponding a -> Value
encoder.
A value that knows how to encode and decode JSON values.
Json.Encode.Value
Represents a JavaScript value.
Json.Decode.Error
A structured error describing exactly how the decoder failed. You can use this to create more elaborate visualizations of a decoder problem. For example, you could show the entire JSON object and show the part causing the failure in red.
Json.Decode.Decoder a
A value that knows how to decode JSON values.
decoder : Codec a -> Decoder a
Extracts the Decoder
contained inside the Codec
.
decodeString : Codec a -> String -> Result Error a
Parse the given string into a JSON value and then run the Codec
on it.
This will fail if the string is not well-formed JSON or if the Codec
fails for some reason.
decodeValue : Codec a -> Value -> Result Error a
Run a Codec
to decode some JSON Value
. You can send these JSON values
through ports, so that is probably the main time you would use this function.
encoder : Codec a -> a -> Value
Extracts the encoding function contained inside the Codec
.
encodeToString : Basics.Int -> Codec a -> a -> String
Convert a value into a prettified JSON string. The first argument specifies the amount of indentation in the result string.
encodeToValue : Codec a -> a -> Value
Convert a value into a Javascript Value
.
string : Codec String
Codec
between a JSON string and an Elm String
bool : Codec Basics.Bool
Codec
between a JSON boolean and an Elm Bool
int : Codec Basics.Int
Codec
between a JSON number and an Elm Int
float : Codec Basics.Float
Codec
between a JSON number and an Elm Float
char : Codec Char
Codec
between a JSON string of length 1 and an Elm Char
enum : Codec a -> List ( a, b ) -> Codec b
Codec
for a fixed list of Elm values.
This can be used for custom types, if they are really simple:
type Semaphore = Red | Yellow | Green
semaphoreCodec : Codec Semaphore
semaphoreCodec =
enum Codec.string
[ ("Red", Red)
, ("Yellow", Yellow)
, ("Green", Green)
]
encodeToString 0 semaphoreCodec Red
--> "\"Red\""
decodeString semaphoreCodec "\"Red\""
--> Ok Red
type Count = One | Two | Three
countCodec : Codec Count
countCodec =
enum Codec.int
[ (1, One)
, (2, Two)
, (3, Three)
]
encodeToString 0 countCodec Two
--> "2"
decodeString countCodec "2"
--> Ok Two
incompleteCodec : Codec Count
incompleteCodec =
enum Codec.int
[ (1, One)
, (2, Two)
]
encodeToString 0 incompleteCodec Three
--> "null"
decodeString incompleteCodec "3" |> Result.mapError (\_ -> "...")
--> Err "..."
maybe : Codec a -> Codec (Maybe a)
Represents an optional value.
This is encoded as null
when the input is Nothing
, and the same as x
when Just x
.
If the decoding using the inner Codec
fails, it will succeed with Nothing
. If you want it to fail use nullable
instead.
encodeToString 0 (maybe int) (Just 3)
--> "3"
encodeToString 0 (maybe int) Nothing
--> "null"
decodeString (maybe int) "3"
--> Ok (Just 3)
decodeString (maybe int) "null"
--> Ok Nothing
decodeString (maybe int) "\"hello\""
--> Ok Nothing
nullable : Codec a -> Codec (Maybe a)
Represents an optional value.
This is encoded as null
when the input is Nothing
, and the same as x
when Just x
.
When decoding, it decodes null
to Nothing
. Otherwise, if the decoding using the inner Codec
fails, it will fail. If you want it to succeed with Nothing
use maybe
instead.
encodeToString 0 (nullable int) (Just 3)
--> "3"
encodeToString 0 (nullable int) Nothing
--> "null"
decodeString (nullable int) "3"
--> Ok (Just 3)
decodeString (nullable int) "null"
--> Ok Nothing
decodeString (nullable int) "\"hello\"" |> Result.mapError (\_ -> "...")
--> Err "..."
list : Codec a -> Codec (List a)
Codec
between a JSON array and an Elm List
.
array : Codec a -> Codec (Array a)
Codec
between a JSON array and an Elm Array
.
dict : Codec a -> Codec (Dict String a)
Codec
between a JSON object and an Elm Dict
.
set : Codec comparable -> Codec (Set comparable)
Codec
between a JSON array and an Elm Set
.
tuple : Codec a -> Codec b -> Codec ( a, b )
Codec
between a JSON array of length 2 and an Elm Tuple
.
triple : Codec a -> Codec b -> Codec c -> Codec ( a, b, c )
Codec
between a JSON array of length 3 and an Elm triple.
result : Codec error -> Codec value -> Codec (Result error value)
Codec
for Result
values.
A partially built Codec
for an object.
object : b -> ObjectCodec a b
Start creating a Codec
for an object. You should pass the main constructor as argument.
If you don't have one (for example it's a simple type with no name), you should pass a function that given the field values builds an object.
Example with constructor:
type alias Point =
{ x : Float
, y : Float
}
pointCodec : Codec Point
pointCodec =
Codec.object Point
|> Codec.field "x" .x Codec.float
|> Codec.field "y" .y Codec.float
|> Codec.buildObject
Example without constructor:
pointCodec : Codec { x : Int, y : Bool }
pointCodec =
Codec.object (\x y -> { x = x, y = y })
|> Codec.field "x" .x Codec.int
|> Codec.field "y" .y Codec.bool
|> Codec.buildObject
field : String -> (a -> f) -> Codec f -> ObjectCodec a (f -> b) -> ObjectCodec a b
Specify the name, getter and Codec
for a field.
The name is only used as the field name in the resulting JSON, and has no impact on the Elm side.
optionalField : String -> (a -> Maybe f) -> Codec f -> ObjectCodec a (Maybe f -> b) -> ObjectCodec a b
Specify the name getter and Codec
for an optional field.
This is particularly useful for evolving your Codec
s.
If the field is not present in the input then it gets decoded to Nothing
. If the field cannot be decoded this will fail. If the value is null
then this will fail, use optionalNullableField
if you want it to succeed instad.
If the optional field's value is Nothing
then the resulting object will not contain that field.
optionalNullableField : String -> (a -> Maybe f) -> Codec f -> ObjectCodec a (Maybe f -> b) -> ObjectCodec a b
Specify the name getter and Codec
for an optional field.
This is particularly useful for evolving your Codec
s.
If the field is not present in the input then it gets decoded to Nothing
. If the field cannot be decoded this will fail. If the value is null
then this will succeed with Nothing
, use optionalField
if you want it to fail instad.
If the optional field's value is Nothing
then the resulting object will not contain that field.
buildObject : ObjectCodec a a -> Codec a
Create a Codec
from a fully specified ObjectCodec
.
A partially built Codec
for a custom type.
custom : match -> CustomCodec match value
Starts building a Codec
for a custom type.
You need to pass a pattern matching function, built like this:
type Semaphore
= Red Int String
| Yellow
| Green Float
semaphoreCodec : Codec Semaphore
semaphoreCodec =
Codec.custom
(\red yellow green value ->
case value of
Red i s ->
red i s
Yellow ->
yellow
Green f ->
green f
)
|> Codec.variant2 "Red" Red Codec.int Codec.string
|> Codec.variant0 "Yellow" Yellow
|> Codec.variant1 "Green" Green Codec.float
|> Codec.buildCustom
variant0 : String -> v -> CustomCodec (Value -> a) v -> CustomCodec a v
Define a variant with 0 parameters for a custom type.
variant1 : String -> (a -> v) -> Codec a -> CustomCodec ((a -> Value) -> b) v -> CustomCodec b v
Define a variant with 1 parameters for a custom type.
variant2 : String -> (a -> b -> v) -> Codec a -> Codec b -> CustomCodec ((a -> b -> Value) -> c) v -> CustomCodec c v
Define a variant with 2 parameters for a custom type.
variant3 : String -> (a -> b -> c -> v) -> Codec a -> Codec b -> Codec c -> CustomCodec ((a -> b -> c -> Value) -> partial) v -> CustomCodec partial v
Define a variant with 3 parameters for a custom type.
variant4 : String -> (a -> b -> c -> d -> v) -> Codec a -> Codec b -> Codec c -> Codec d -> CustomCodec ((a -> b -> c -> d -> Value) -> partial) v -> CustomCodec partial v
Define a variant with 4 parameters for a custom type.
variant5 : String -> (a -> b -> c -> d -> e -> v) -> Codec a -> Codec b -> Codec c -> Codec d -> Codec e -> CustomCodec ((a -> b -> c -> d -> e -> Value) -> partial) v -> CustomCodec partial v
Define a variant with 5 parameters for a custom type.
variant6 : String -> (a -> b -> c -> d -> e -> f -> v) -> Codec a -> Codec b -> Codec c -> Codec d -> Codec e -> Codec f -> CustomCodec ((a -> b -> c -> d -> e -> f -> Value) -> partial) v -> CustomCodec partial v
Define a variant with 6 parameters for a custom type.
variant7 : String -> (a -> b -> c -> d -> e -> f -> g -> v) -> Codec a -> Codec b -> Codec c -> Codec d -> Codec e -> Codec f -> Codec g -> CustomCodec ((a -> b -> c -> d -> e -> f -> g -> Value) -> partial) v -> CustomCodec partial v
Define a variant with 7 parameters for a custom type.
variant8 : String -> (a -> b -> c -> d -> e -> f -> g -> h -> v) -> Codec a -> Codec b -> Codec c -> Codec d -> Codec e -> Codec f -> Codec g -> Codec h -> CustomCodec ((a -> b -> c -> d -> e -> f -> g -> h -> Value) -> partial) v -> CustomCodec partial v
Define a variant with 8 parameters for a custom type.
buildCustom : CustomCodec (a -> Value) a -> Codec a
Build a Codec
for a fully specified custom type.
oneOf : Codec a -> List (Codec a) -> Codec a
Try a set of decoders (in order). The first argument is used for encoding and decoding, the list of other codecs is used as a fallback while decoding.
This is particularly useful for backwards compatibility. You would pass the current codec as the first argument,
and the old ones (eventually map
ped) as a fallback list to use while decoding.
map : (a -> b) -> (b -> a) -> Codec a -> Codec b
Transform a Codec
.
succeed : a -> Codec a
Create a Codec
that produces null as JSON and always decodes as the same value.
recursive : (Codec a -> Codec a) -> Codec a
Create a Codec
for a recursive data structure.
The argument to the function you need to pass is the fully formed Codec
.
fail : String -> Codec a
Ignore the JSON and make the decoder fail. This is handy when used with
oneOf
or andThen
where you want to give a custom error message in some
case. The encoder will produce null
.
andThen : (a -> Codec b) -> (b -> a) -> Codec a -> Codec b
Create codecs that depend on previous results.
lazy : (() -> Codec a) -> Codec a
This is useful for recursive structures that are not easily modeled with recursive
.
Have a look at the Json.Decode docs for examples.
value : Codec Value
Create a Codec
that doesn't transform the JSON value, just brings it to and from Elm as a Value
.
build : (a -> Value) -> Decoder a -> Codec a
Build your own custom Codec
.
Useful if you have pre-existing Decoder
s you need to use.
constant : a -> Codec a
Create a Codec
that produces null as JSON and always decodes as the same value. Obsolete alias of succeed
, will be removed in a future version.
nullableField : String -> (a -> Maybe f) -> Codec f -> ObjectCodec a (Maybe f -> b) -> ObjectCodec a b
Specify the name getter and Codec
for a required field, whose value can be null
.
Warning! This is a footgun and thus deprecated, you should probably use field
with nullable
instead.
If the field is not present in the input then the decoding fails. If the field is present but can't be decoded then the decoding succeeds with Nothing
.
If the field's value is Nothing
then the resulting object will contain the field with a null
value.
This is a shorthand for a field having a Codec
built using maybe
.
maybeField : String -> (a -> Maybe f) -> Codec f -> ObjectCodec a (Maybe f -> b) -> ObjectCodec a b
Specify the name getter and Codec
for an optional field.
Warning! This is a footgun and thus deprecated, you should probably use optionalField
instead.
This is particularly useful for evolving your Codec
s.
If the field is not present in the input then it gets decoded to Nothing
. _If the field value cannot be decoded by the given Codec
it also gets decoded to Nothing
. Even worse, if the input is not an object, this Codec
still succeeds!
When encoding, if the optional field's value is Nothing
then the resulting object will not contain that field.