A Codec a
contain a JSON Decoder a
and the corresponding a -> Value
encoder.
This module is a port of miniBill/elm-codec
. Thank you for the great API design miniBill!
TsJson.Internal.Codec.Codec a
A value that knows how to encode and decode JSON values.
decoder : Codec a -> TsJson.Decode.Decoder a
Extracts the Decoder
contained inside the Codec
.
encoder : Codec a -> TsJson.Internal.Encode.Encoder a
Extracts the encoding function contained inside the Codec
.
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
literal : value -> Json.Encode.Value -> Codec value
stringLiteral : value -> String -> Codec value
maybe : Codec a -> Codec (Maybe a)
Represents an optional value.
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.
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.
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 optional field's value is Nothing
then the resulting object will not contain that field.
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
.
If the field is not present in the input then the decoding fails.
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 Codec.maybe
.
buildObject : ObjectCodec a a -> Codec a
Create a Codec
from a fully specified ObjectCodec
.
stringUnion : List ( String, value ) -> Codec value
Simple one-to-one mapping of Elm values to TypeScript strings (no arguments, just like values like an enumeration).
import TsJson.Codec exposing (Codec)
type DarkMode
= Dark
| Light
darkModeCodec : Codec DarkMode
darkModeCodec =
Codec.stringUnion [ ( "dark", Dark ), ( "light", Light ) ]
The TsType
for darkModeCodec
is the following union:
"dark" | "light"
A partially built Codec
for a custom type.
custom : Maybe String -> match -> CustomCodec match value
Starts building a Codec
for a custom type.
You need to pass a pattern matching function, built like this:
import TsJson.Codec exposing (Codec)
type Shape
= Rectangle Int Int
| Square Int
| Circle Int
shapeCodec : Codec Shape
shapeCodec =
Codec.custom (Just "shape")
(\vRectangle vSquare vCircle shape ->
case shape of
Rectangle width height ->
vRectangle width height
Square width ->
vSquare width
Circle radius ->
vCircle radius
)
|> Codec.namedVariant2 "rectangle" Rectangle ( "width", Codec.int ) ( "height", Codec.int )
|> Codec.positionalVariant1 "square" Square Codec.int
|> Codec.namedVariant1 "circle" Circle ( "radius", Codec.int )
|> Codec.buildCustom
The `TsType` for `shapeCodec` is the following discriminated union:
```typescript
| { shape: "rectangle"; width: number; height: number }
| { shape: "square"; args: [ number ] }
| { shape: "circle"; radius: number }
```
buildCustom : CustomCodec (a -> TsJson.Encode.UnionEncodeValue) a -> Codec a
Build a Codec
for a fully specified custom type.
variant0 : String -> v -> CustomCodec (TsJson.Encode.UnionEncodeValue -> c) v -> CustomCodec c v
Define a variant with 0 parameters for a custom type.
namedVariant1 : String -> (a -> v) -> ( String, Codec a ) -> CustomCodec ((a -> TsJson.Internal.Encode.UnionEncodeValue) -> c) v -> CustomCodec c v
Define a variant with 1 parameter for a custom type.
namedVariant2 : String -> (a -> b -> v) -> ( String, Codec a ) -> ( String, Codec b ) -> CustomCodec ((a -> b -> TsJson.Encode.UnionEncodeValue) -> c) v -> CustomCodec c v
Define a variant with 2 parameters for a custom type.
namedVariant3 : String -> (a1 -> a2 -> a3 -> v) -> ( String, Codec a1 ) -> ( String, Codec a2 ) -> ( String, Codec a3 ) -> CustomCodec ((a1 -> a2 -> a3 -> TsJson.Encode.UnionEncodeValue) -> c) v -> CustomCodec c v
Define a variant with 3 parameters for a custom type.
namedVariant4 : String -> (a1 -> a2 -> a3 -> a4 -> v) -> ( String, Codec a1 ) -> ( String, Codec a2 ) -> ( String, Codec a3 ) -> ( String, Codec a4 ) -> CustomCodec ((a1 -> a2 -> a3 -> a4 -> TsJson.Encode.UnionEncodeValue) -> c) v -> CustomCodec c v
Define a variant with 4 parameters for a custom type.
namedVariant5 : String -> (a1 -> a2 -> a3 -> a4 -> a5 -> v) -> ( String, Codec a1 ) -> ( String, Codec a2 ) -> ( String, Codec a3 ) -> ( String, Codec a4 ) -> ( String, Codec a5 ) -> CustomCodec ((a1 -> a2 -> a3 -> a4 -> a5 -> TsJson.Encode.UnionEncodeValue) -> c) v -> CustomCodec c v
Define a variant with 5 parameters for a custom type.
namedVariant6 : String -> (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> v) -> ( String, Codec a1 ) -> ( String, Codec a2 ) -> ( String, Codec a3 ) -> ( String, Codec a4 ) -> ( String, Codec a5 ) -> ( String, Codec a6 ) -> CustomCodec ((a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> TsJson.Encode.UnionEncodeValue) -> c) v -> CustomCodec c v
Define a variant with 6 parameters for a custom type.
namedVariant7 : String -> (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> v) -> ( String, Codec a1 ) -> ( String, Codec a2 ) -> ( String, Codec a3 ) -> ( String, Codec a4 ) -> ( String, Codec a5 ) -> ( String, Codec a6 ) -> ( String, Codec a7 ) -> CustomCodec ((a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> TsJson.Encode.UnionEncodeValue) -> c) v -> CustomCodec c v
Define a variant with 7 parameters for a custom type.
namedVariant8 : String -> (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> v) -> ( String, Codec a1 ) -> ( String, Codec a2 ) -> ( String, Codec a3 ) -> ( String, Codec a4 ) -> ( String, Codec a5 ) -> ( String, Codec a6 ) -> ( String, Codec a7 ) -> ( String, Codec a8 ) -> CustomCodec ((a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> a8 -> TsJson.Encode.UnionEncodeValue) -> c) v -> CustomCodec c v
Define a variant with 8 parameters for a custom type.
positionalVariant1 : String -> (arg1 -> v) -> Codec arg1 -> CustomCodec ((arg1 -> TsJson.Encode.UnionEncodeValue) -> c) v -> CustomCodec c v
Define a variant with 0 parameters for a custom type.
positionalVariant2 : String -> (arg1 -> arg2 -> v) -> Codec arg1 -> Codec arg2 -> CustomCodec ((arg1 -> arg2 -> TsJson.Encode.UnionEncodeValue) -> c) v -> CustomCodec c v
Define a variant with 2 parameters for a custom type.
positionalVariant3 : String -> (arg1 -> arg2 -> arg3 -> v) -> Codec arg1 -> Codec arg2 -> Codec arg3 -> CustomCodec ((arg1 -> arg2 -> arg3 -> TsJson.Encode.UnionEncodeValue) -> partial) v -> CustomCodec partial v
Define a variant with 3 parameters for a custom type.
positionalVariant4 : String -> (arg1 -> arg2 -> arg3 -> arg4 -> v) -> Codec arg1 -> Codec arg2 -> Codec arg3 -> Codec arg4 -> CustomCodec ((arg1 -> arg2 -> arg3 -> arg4 -> TsJson.Encode.UnionEncodeValue) -> partial) v -> CustomCodec partial v
Define a variant with 3 parameters for a custom type.
positionalVariant5 : String -> (arg1 -> arg2 -> arg3 -> arg4 -> arg5 -> v) -> Codec arg1 -> Codec arg2 -> Codec arg3 -> Codec arg4 -> Codec arg5 -> CustomCodec ((arg1 -> arg2 -> arg3 -> arg4 -> arg5 -> TsJson.Encode.UnionEncodeValue) -> partial) v -> CustomCodec partial v
Define a variant with 3 parameters for a custom type.
positionalVariant6 : String -> (arg1 -> arg2 -> arg3 -> arg4 -> arg5 -> arg6 -> v) -> Codec arg1 -> Codec arg2 -> Codec arg3 -> Codec arg4 -> Codec arg5 -> Codec arg6 -> CustomCodec ((arg1 -> arg2 -> arg3 -> arg4 -> arg5 -> arg6 -> TsJson.Encode.UnionEncodeValue) -> partial) v -> CustomCodec partial v
Define a variant with 3 parameters for a custom type.
positionalVariant7 : String -> (arg1 -> arg2 -> arg3 -> arg4 -> arg5 -> arg6 -> arg7 -> v) -> Codec arg1 -> Codec arg2 -> Codec arg3 -> Codec arg4 -> Codec arg5 -> Codec arg6 -> Codec arg7 -> CustomCodec ((arg1 -> arg2 -> arg3 -> arg4 -> arg5 -> arg6 -> arg7 -> TsJson.Encode.UnionEncodeValue) -> partial) v -> CustomCodec partial v
Define a variant with 3 parameters for a custom type.
positionalVariant8 : String -> (arg1 -> arg2 -> arg3 -> arg4 -> arg5 -> arg6 -> arg7 -> arg8 -> v) -> Codec arg1 -> Codec arg2 -> Codec arg3 -> Codec arg4 -> Codec arg5 -> Codec arg6 -> Codec arg7 -> Codec arg8 -> CustomCodec ((arg1 -> arg2 -> arg3 -> arg4 -> arg5 -> arg6 -> arg7 -> arg8 -> TsJson.Encode.UnionEncodeValue) -> partial) v -> CustomCodec partial v
Define a variant with 3 parameters for a 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
where you want to give a custom error message in some
case. The encoder will produce null
.
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 Json.Decode.Value
Create a Codec
that doesn't transform the JSON value, just brings it to and from Elm as a Value
.
build : TsJson.Internal.Encode.Encoder a -> TsJson.Decode.Decoder a -> Codec a
Build your own custom Codec
.
Useful if you have pre-existing Decoder
s you need to use.
tsType : Codec value -> Internal.TsJsonType.TsType