The following is an example of how to:
- create a nested record type
- encode this as JSON
- decode a JSON string to an entity
- create a random Entity generator
- test the JSON parsing of the Entity
type alias Vector =
{ x : Float
, y : Float
, z : Float
}
type alias Transform =
{ position : Vector
, rotation : Vector
, scale : Vector
}
type alias ID = Int
type alias Entity =
{ name : String
, id : ID
, transform : Transform
,
}
-- Encoding (Using Encode namespace)
entity : Entity -> String
entity ent = object
[ "name" := string ent.name
, "id" := id ent.id
, "transform" : transform ent.transform
]
transform : Transform -> String
transform {position, rotation, scale} = object
[ "position" := vector position
, "rotation" := vector rotation
, "scale" := vector scale
]
vector : Vector -> String
vector {x, y, z} = object
[ "x" := float x
, "y" := float y
, "z" := float z
]
id : ID -> String
id = int
-- Decoding (Using Decoder namespace)
entity : Decoder Entity
entity = Entity
`map` "name" := string
`andMap` "id" := id
`andMap` "transform" := transform
transform : Decoder Transform
transform = Transform
`map` "position" := vector
`andMap` "rotation" := vector
`andMap` "scale" := scale
vector : Decoder Vector
vector = Vector
`map` "x" := float
`andMap` "y" := float
`andMap` "z" := float
id : Decoder ID
id = int
-- Random Generator (Under Random namespace)
entity : Generator Entity
entity = Entity
`map` rangeLengthString 1 20 unicode
`andMap` anyInt
`andMap` transform
transform : Generator Transform
transform = Transform
`map` vector
`andMap` vector
`andMap` vector
vector : Generator Vector
vector = Vector
`map` anyFloat
`andMap` anyFloat
`andMap` anyFloat
--- Property Test
test_encodeDecode : Entity -> Bool
test_encodeDecode entity =
let
encoded = Encode.entity entity
decoded = decodeString Decode.entity entity
in case decoded of
Err _ -> False
Ok value -> entity == value
prop_encodingAndDecodingAreInverses : Property
prop_encodingAndDecodingAreInverses = property
"Encoding an Entity and then decoding that encode should return the original Entity"
test_encodeDecode Random.entity