let { Deserialize } = import! std.json.de #[derive(Show, Eq, Deserialize)] type Record = { x : Int } #[derive(Show, Eq, Deserialize)] type Record2 = { x : Int, y : String } #[derive(Show, Eq, Deserialize)] type Recursive = { record : Record, y : Float } #[derive(Show, Eq, Deserialize)] type Variant = | Int Int | String String let result @ { Result, ? } = import! std.result let de @ { Deserializer, ValueDeserializer, Deserialize, field, deserializer, ? } = import! std.json.de let { Test, run, assert, assert_eq, test, group, ? } = import! std.test let { Applicative, (*>) } = import! std.applicative let { map } = import! std.functor let { (<|) } = import! std.function let int = import! std.int let list @ { List, ? } = import! std.list let { ? } = import! std.array let { (<>) } = import! std.semigroup group "json.de" [ test "derive_record_1_field" <| \_ -> assert_eq (de.deserialize r#"{ "x" : 1 }"#) (Ok { x = 1 }), test "derive_record_2_fields" <| \_ -> assert_eq (de.deserialize r#"{ "y" : "abc", "x" : 1 }"#) (Ok { x = 1, y = "abc" }), test "derive_record_recursive" <| \_ -> assert_eq (de.deserialize r#"{ "record" : { "y" : "abc", "x" : 1 }, "y" : 1 } "#) (Ok { record = { x = 1 }, y = 1.0 }), group "alternative" ( let { (<|>) } = import! std.alternative let d : ValueDeserializer _ = de.int <|> map (\s -> result.unwrap_ok (int.parse s)) de.string [ test "or_first" <| \_ -> assert_eq (de.deserialize_with d r#" 123 "#) (Ok 123), test "or_second" <| \_ -> assert_eq (de.deserialize_with d r#" "456" "#) (Ok 456), ] ), group "variant" [ test "derive_variant" <| \_ -> assert_eq (de.deserialize r#" 123 "#) (Ok (Int 123)), ], group "option" ( let d : ValueDeserializer (Option Record) = deserializer [ test "none" <| \_ -> assert_eq (de.deserialize_with d r#" null "#) (Ok None), test "some" <| \_ -> assert_eq (de.deserialize_with d r#" { "x": 1 } "#) (Ok (Some { x = 1 })), ] ), group "list" ( let d : ValueDeserializer (List Record) = deserializer [ test "empty" <| \_ -> assert_eq (de.deserialize_with d r#" [] "#) (Ok Nil), test "some" <| \_ -> let actual = de.deserialize_with d r#" [{ "x": 1 }, { "x": 2 }] "# assert_eq actual (Ok (list.of [{ x = 1 }, { x = 2 }])), ] ), group "array" ( let d : ValueDeserializer (Array Record) = deserializer [ test "empty" <| \_ -> assert_eq (de.deserialize_with d r#" [] "#) (Ok []), test "some" <| \_ -> let actual = de.deserialize_with d r#" [{ "x": 1 }, { "x": 2 }] "# assert_eq actual (Ok ([{ x = 1 }, { x = 2 }])), ] ), group "array" ( let map @ { Map, ? } = import! std.map let d : ValueDeserializer (Map String Int) = deserializer [ test "empty" <| \_ -> assert_eq (de.deserialize_with d r#" {} "#) (Ok map.empty), test "some" <| \_ -> let actual = de.deserialize_with d r#" { "x": 1, "y": 2 } "# assert_eq actual (Ok (map.singleton "x" 1 <> map.singleton "y" 2)) ] ), ]