@greenlabs/ppx-spice 0.1.8 → 0.1.9-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +4 -0
  3. package/docs/GUIDE.md +139 -0
  4. package/package.json +1 -1
  5. package/ppx-windows.exe +0 -0
  6. package/.github/workflows/build_linux.yml +0 -41
  7. package/.github/workflows/build_macos.yml +0 -41
  8. package/.github/workflows/build_windows.yml +0 -41
  9. package/.github/workflows/print_esy_cache.js +0 -13
  10. package/.github/workflows/publish.yml +0 -161
  11. package/.github/workflows/publish_prerelease.yml +0 -177
  12. package/.vscode/settings.json +0 -6
  13. package/src/.ocamlformat +0 -0
  14. package/src/bin/bin.ml +0 -1
  15. package/src/bin/dune +0 -5
  16. package/src/dune +0 -1
  17. package/src/dune-project +0 -2
  18. package/src/dune-workspace +0 -3
  19. package/src/esy.lock/.gitattributes +0 -3
  20. package/src/esy.lock/.gitignore +0 -3
  21. package/src/esy.lock/index.json +0 -1196
  22. package/src/esy.lock/opam/astring.0.8.5/opam +0 -37
  23. package/src/esy.lock/opam/base-bytes.base/opam +0 -9
  24. package/src/esy.lock/opam/base-threads.base/opam +0 -6
  25. package/src/esy.lock/opam/base-unix.base/opam +0 -6
  26. package/src/esy.lock/opam/base.v0.14.1/opam +0 -36
  27. package/src/esy.lock/opam/biniou.1.2.1/opam +0 -45
  28. package/src/esy.lock/opam/cmdliner.1.0.4/opam +0 -36
  29. package/src/esy.lock/opam/cppo.1.6.8/opam +0 -37
  30. package/src/esy.lock/opam/csexp.1.5.1/opam +0 -60
  31. package/src/esy.lock/opam/dot-merlin-reader.4.1/opam +0 -30
  32. package/src/esy.lock/opam/dune-build-info.2.9.1/opam +0 -42
  33. package/src/esy.lock/opam/dune-configurator.2.9.1/opam +0 -47
  34. package/src/esy.lock/opam/dune.2.9.1/opam +0 -58
  35. package/src/esy.lock/opam/easy-format.1.3.2/opam +0 -46
  36. package/src/esy.lock/opam/fix.20201120/opam +0 -24
  37. package/src/esy.lock/opam/fpath.0.7.3/opam +0 -36
  38. package/src/esy.lock/opam/menhir.20211012/opam +0 -28
  39. package/src/esy.lock/opam/menhirLib.20211012/opam +0 -29
  40. package/src/esy.lock/opam/menhirSdk.20211012/opam +0 -29
  41. package/src/esy.lock/opam/ocaml-compiler-libs.v0.12.4/opam +0 -39
  42. package/src/esy.lock/opam/ocaml-lsp-server.1.8.3/opam +0 -54
  43. package/src/esy.lock/opam/ocamlbuild.0.14.0/opam +0 -36
  44. package/src/esy.lock/opam/ocamlfind.1.9.1/opam +0 -44
  45. package/src/esy.lock/opam/ocamlformat-rpc-lib.0.18.0/opam +0 -40
  46. package/src/esy.lock/opam/ocamlformat.0.19.0/opam +0 -55
  47. package/src/esy.lock/opam/ocp-indent.1.8.1/opam +0 -57
  48. package/src/esy.lock/opam/odoc-parser.0.9.0/opam +0 -45
  49. package/src/esy.lock/opam/pp.1.1.2/opam +0 -58
  50. package/src/esy.lock/opam/ppx_derivers.1.2.1/opam +0 -23
  51. package/src/esy.lock/opam/ppx_yojson_conv_lib.v0.14.0/opam +0 -24
  52. package/src/esy.lock/opam/ppxlib.0.23.0/opam +0 -62
  53. package/src/esy.lock/opam/re.1.10.3/opam +0 -46
  54. package/src/esy.lock/opam/result.1.5/opam +0 -22
  55. package/src/esy.lock/opam/seq.base/files/META.seq +0 -4
  56. package/src/esy.lock/opam/seq.base/files/seq.install +0 -3
  57. package/src/esy.lock/opam/seq.base/opam +0 -15
  58. package/src/esy.lock/opam/sexplib0.v0.14.0/opam +0 -26
  59. package/src/esy.lock/opam/stdio.v0.14.0/opam +0 -27
  60. package/src/esy.lock/opam/stdlib-shims.0.3.0/opam +0 -31
  61. package/src/esy.lock/opam/topkg.1.0.4/opam +0 -44
  62. package/src/esy.lock/opam/uchar.0.0.2/opam +0 -36
  63. package/src/esy.lock/opam/uucp.14.0.0/opam +0 -41
  64. package/src/esy.lock/opam/uuseg.14.0.0/opam +0 -43
  65. package/src/esy.lock/opam/uutf.1.0.2/opam +0 -40
  66. package/src/esy.lock/opam/yojson.1.7.0/opam +0 -38
  67. package/src/esy.lock/overrides/opam__s__ocamlbuild_opam__c__0.14.0_opam_override/files/ocamlbuild-0.14.0.patch +0 -463
  68. package/src/esy.lock/overrides/opam__s__ocamlbuild_opam__c__0.14.0_opam_override/package.json +0 -27
  69. package/src/esy.lock/overrides/opam__s__ocamlfind_opam__c__1.9.1_opam_override/files/findlib-1.9.1.patch +0 -471
  70. package/src/esy.lock/overrides/opam__s__ocamlfind_opam__c__1.9.1_opam_override/package.json +0 -61
  71. package/src/ppx/codecs.ml +0 -120
  72. package/src/ppx/decode_cases.ml +0 -18
  73. package/src/ppx/dune +0 -9
  74. package/src/ppx/polyvariants.ml +0 -288
  75. package/src/ppx/ppx_spice.ml +0 -19
  76. package/src/ppx/records.ml +0 -163
  77. package/src/ppx/signature.ml +0 -86
  78. package/src/ppx/structure.ml +0 -109
  79. package/src/ppx/tuple.ml +0 -68
  80. package/src/ppx/utils.ml +0 -117
  81. package/src/ppx/variants.ml +0 -257
  82. package/src/ppx_spice.opam +0 -21
  83. package/test/__tests__/test_optional_field_records.js +0 -91
  84. package/test/__tests__/test_optional_field_records.res +0 -98
  85. package/test/__tests__/test_polyvariants.js +0 -57
  86. package/test/__tests__/test_polyvariants.res +0 -41
  87. package/test/__tests__/test_records.js +0 -100
  88. package/test/__tests__/test_records.res +0 -111
  89. package/test/__tests__/test_variants.js +0 -85
  90. package/test/__tests__/test_variants.res +0 -63
  91. package/test/bsconfig.json +0 -27
  92. package/test/package.json +0 -18
  93. package/test/src/OptionalFieldRecords.js +0 -237
  94. package/test/src/OptionalFieldRecords.res +0 -23
  95. package/test/src/Polyvariants.js +0 -94
  96. package/test/src/Polyvariants.res +0 -5
  97. package/test/src/Polyvariants.resi +0 -5
  98. package/test/src/Records.js +0 -186
  99. package/test/src/Records.res +0 -17
  100. package/test/src/Records.resi +0 -17
  101. package/test/src/Spice.js +0 -448
  102. package/test/src/Spice_Codecs.js +0 -57
  103. package/test/src/Variants.js +0 -115
  104. package/test/src/Variants.res +0 -11
  105. package/test/src/Variants.resi +0 -11
  106. package/test/yarn.lock +0 -4194
package/src/ppx/tuple.ml DELETED
@@ -1,68 +0,0 @@
1
- open Ppxlib
2
- open Parsetree
3
- open Ast_helper
4
- open Utils
5
-
6
- let generate_encoder composite_encoders =
7
- let arrExp =
8
- composite_encoders
9
- |> List.mapi (fun i e ->
10
- let vExp = Exp.ident (lid ("v" ^ string_of_int i)) in
11
- [%expr [%e e] [%e vExp]])
12
- |> Exp.array
13
- in
14
- let deconstructor_pattern =
15
- composite_encoders
16
- |> List.mapi (fun i _ -> Pat.var (mknoloc ("v" ^ string_of_int i)))
17
- |> Pat.tuple
18
- in
19
- [%expr fun [%p deconstructor_pattern] -> [%e arrExp] |> Js.Json.array]
20
-
21
- let generate_decode_success_case num_args =
22
- {
23
- pc_lhs =
24
- Array.init num_args (fun i ->
25
- mknoloc ("v" ^ string_of_int i) |> Pat.var |> fun p ->
26
- [%pat? Belt.Result.Ok [%p p]])
27
- |> Array.to_list
28
- |> tuple_or_singleton Pat.tuple;
29
- pc_guard = None;
30
- pc_rhs =
31
- ( Array.init num_args (fun i -> make_ident_expr ("v" ^ string_of_int i))
32
- |> Array.to_list |> Exp.tuple
33
- |> fun e -> [%expr Belt.Result.Ok [%e e]] );
34
- }
35
-
36
- let generate_decode_switch composite_decoders =
37
- let decode_expr =
38
- composite_decoders
39
- |> List.mapi (fun i d ->
40
- let ident = make_ident_expr ("v" ^ string_of_int i) in
41
- [%expr [%e d] [%e ident]])
42
- |> Exp.tuple
43
- in
44
- composite_decoders
45
- |> List.mapi
46
- (Decode_cases.generate_error_case (List.length composite_decoders))
47
- |> List.append
48
- [ generate_decode_success_case (List.length composite_decoders) ]
49
- |> Exp.match_ decode_expr
50
-
51
- let generate_decoder composite_decoders =
52
- let match_arr_pattern =
53
- composite_decoders
54
- |> List.mapi (fun i _ -> Pat.var (mknoloc ("v" ^ string_of_int i)))
55
- |> Pat.array
56
- in
57
- let match_pattern = [%pat? Js.Json.JSONArray [%p match_arr_pattern]] in
58
- let outer_switch =
59
- Exp.match_ [%expr Js.Json.classify json]
60
- [
61
- Exp.case match_pattern (generate_decode_switch composite_decoders);
62
- Exp.case
63
- [%pat? Js.Json.JSONArray _]
64
- [%expr Spice.error "Incorrect cardinality" json];
65
- Exp.case [%pat? _] [%expr Spice.error "Not a tuple" json];
66
- ]
67
- in
68
- [%expr fun json -> [%e outer_switch]]
package/src/ppx/utils.ml DELETED
@@ -1,117 +0,0 @@
1
- open Ppxlib
2
- open Parsetree
3
- open Ast_helper
4
-
5
- let annotation_name = "spice"
6
-
7
- let encoder_func_suffix = "_encode"
8
-
9
- let decoder_func_suffix = "_decode"
10
-
11
- let encoder_var_prefix = "encoder_"
12
-
13
- let decoder_var_prefix = "decoder_"
14
-
15
- let loc = !default_loc
16
-
17
- let fail loc message = Location.raise_errorf ~loc "%s" message
18
-
19
- let longident_parse = Longident.parse [@@ocaml.warning "-3"]
20
-
21
- let mkloc txt loc = { Location.txt; loc }
22
-
23
- let mknoloc txt = mkloc txt Location.none
24
-
25
- let lid ?(loc = Location.none) s = mkloc (Longident.parse s) loc
26
-
27
- let make_ident_expr ?attrs s = Exp.ident ?attrs (mknoloc (longident_parse s))
28
-
29
- let tuple_or_singleton tuple l =
30
- match List.length l > 1 with true -> tuple l | false -> List.hd l
31
-
32
- let get_attribute_by_name attributes name =
33
- let filtered =
34
- attributes
35
- |> List.filter (fun { attr_name = { Location.txt } } -> txt = name)
36
- in
37
- match filtered with
38
- | [] -> Ok None
39
- | [ attribute ] -> Ok (Some attribute)
40
- | _ -> Error ("Too many occurrences of \"" ^ name ^ "\" attribute")
41
-
42
- type generator_settings = { do_encode : bool; do_decode : bool }
43
-
44
- let get_generator_settings_from_attributes attributes =
45
- match get_attribute_by_name attributes annotation_name with
46
- | Ok None -> (
47
- match
48
- ( get_attribute_by_name attributes (annotation_name ^ ".decode"),
49
- get_attribute_by_name attributes (annotation_name ^ ".encode") )
50
- with
51
- | Ok (Some _), Ok (Some _) ->
52
- Ok (Some { do_encode = true; do_decode = true })
53
- | Ok (Some _), Ok None ->
54
- Ok (Some { do_encode = false; do_decode = true })
55
- | Ok None, Ok (Some _) ->
56
- Ok (Some { do_encode = true; do_decode = false })
57
- | Ok None, Ok None -> Ok None
58
- | (Error _ as e), _ -> e
59
- | _, (Error _ as e) -> e)
60
- | Ok (Some _) -> Ok (Some { do_encode = true; do_decode = true })
61
- | Error _ as e -> e
62
-
63
- let get_expression_from_payload { attr_name = { loc }; attr_payload = payload }
64
- =
65
- match payload with
66
- | PStr [ { pstr_desc } ] -> (
67
- match pstr_desc with
68
- | Pstr_eval (expr, _) -> expr
69
- | _ -> fail loc "Expected expression as attribute payload")
70
- | _ -> fail loc "Expected expression as attribute payload"
71
-
72
- let get_param_names params =
73
- params
74
- |> List.map (fun ({ ptyp_desc; ptyp_loc }, _) ->
75
- match ptyp_desc with
76
- | Ptyp_var s -> s
77
- | _ ->
78
- fail ptyp_loc "Unhandled param type" |> fun v ->
79
- Location.Error v |> raise)
80
-
81
- let get_string_from_expression { pexp_desc; pexp_loc } =
82
- match pexp_desc with
83
- | Pexp_constant const -> (
84
- match const with
85
- | Pconst_string (name, loc, delimit) -> (name, loc, delimit)
86
- | _ -> fail pexp_loc "cannot find a name??")
87
- | _ -> fail pexp_loc "cannot find a name??"
88
-
89
- let index_const i =
90
- Pconst_string ("[" ^ string_of_int i ^ "]", Location.none, None)
91
- |> Exp.constant
92
-
93
- let rec is_identifier_used_in_core_type type_name { ptyp_desc; ptyp_loc } =
94
- match ptyp_desc with
95
- | Ptyp_arrow (_, _, _) ->
96
- fail ptyp_loc "Can't generate codecs for function type"
97
- | Ptyp_any -> fail ptyp_loc "Can't generate codecs for `any` type"
98
- | Ptyp_package _ -> fail ptyp_loc "Can't generate codecs for module type"
99
- | Ptyp_variant (_, _, _) -> fail ptyp_loc "Unexpected Ptyp_variant"
100
- | Ptyp_var _ -> false
101
- | Ptyp_tuple child_types ->
102
- List.exists (is_identifier_used_in_core_type type_name) child_types
103
- | Ptyp_constr ({ txt }, child_types) -> (
104
- match txt = Lident type_name with
105
- | true -> true
106
- | false ->
107
- List.exists (is_identifier_used_in_core_type type_name) child_types)
108
- | _ -> fail ptyp_loc "This syntax is not yet handled by spice"
109
-
110
- let attr_warning expr =
111
- {
112
- attr_name = mkloc "ocaml.warning" loc;
113
- attr_payload = PStr [ { pstr_desc = Pstr_eval (expr, []); pstr_loc = loc } ];
114
- attr_loc = loc;
115
- }
116
-
117
- let some_if_true cond a = match cond with true -> Some a | false -> None
@@ -1,257 +0,0 @@
1
- open Ppxlib
2
- open Parsetree
3
- open Ast_helper
4
- open Utils
5
-
6
- type parsed_decl = {
7
- name : string;
8
- alias : expression;
9
- has_attr_as : bool;
10
- constr_decl : Parsetree.constructor_declaration;
11
- }
12
-
13
- let generate_encoder_case generator_settings unboxed has_attr_as
14
- { name; alias; constr_decl = { pcd_args; pcd_loc } } =
15
- match pcd_args with
16
- | Pcstr_tuple args ->
17
- let alias_name, _, delimit = get_string_from_expression alias in
18
- let constructor_expr =
19
- Exp.constant (Pconst_string (alias_name, Location.none, delimit))
20
- in
21
- let lhs_vars =
22
- match args with
23
- | [] -> None
24
- | [ _ ] -> Some (Pat.var (mknoloc "v0"))
25
- | _ ->
26
- args
27
- |> List.mapi (fun i _ ->
28
- mkloc ("v" ^ string_of_int i) pcd_loc |> Pat.var)
29
- |> Pat.tuple
30
- |> fun v -> Some v
31
- in
32
- let rhs_list =
33
- args
34
- |> List.map (Codecs.generate_codecs generator_settings)
35
- |> List.map (fun (encoder, _) -> Option.get encoder)
36
- |> List.mapi (fun i e ->
37
- Exp.apply ~loc:pcd_loc e
38
- [ (Asttypes.Nolabel, make_ident_expr ("v" ^ string_of_int i)) ])
39
- |> List.append [ [%expr Js.Json.string [%e constructor_expr]] ]
40
- in
41
-
42
- {
43
- pc_lhs = Pat.construct (lid name) lhs_vars;
44
- pc_guard = None;
45
- pc_rhs =
46
- (if unboxed then List.tl rhs_list |> List.hd
47
- else if has_attr_as then [%expr Js.Json.string [%e constructor_expr]]
48
- else [%expr Js.Json.array [%e rhs_list |> Exp.array]]);
49
- }
50
- | Pcstr_record _ -> fail pcd_loc "This syntax is not yet implemented by spice"
51
-
52
- let generate_decode_success_case num_args constructor_name =
53
- {
54
- pc_lhs =
55
- Array.init num_args (fun i ->
56
- mknoloc ("v" ^ string_of_int i) |> Pat.var |> fun p ->
57
- [%pat? Belt.Result.Ok [%p p]])
58
- |> Array.to_list
59
- |> tuple_or_singleton Pat.tuple;
60
- pc_guard = None;
61
- pc_rhs =
62
- ( Array.init num_args (fun i -> make_ident_expr ("v" ^ string_of_int i))
63
- |> Array.to_list
64
- |> tuple_or_singleton Exp.tuple
65
- |> fun v ->
66
- Some v |> Exp.construct (lid constructor_name) |> fun e ->
67
- [%expr Belt.Result.Ok [%e e]] );
68
- }
69
-
70
- let generate_arg_decoder generator_settings args constructor_name =
71
- let num_args = List.length args in
72
- args
73
- |> List.mapi (Decode_cases.generate_error_case num_args)
74
- |> List.append [ generate_decode_success_case num_args constructor_name ]
75
- |> Exp.match_
76
- (args
77
- |> List.map (Codecs.generate_codecs generator_settings)
78
- |> List.mapi (fun i (_, decoder) ->
79
- Exp.apply (Option.get decoder)
80
- [
81
- ( Asttypes.Nolabel,
82
- (* +1 because index 0 is the constructor *)
83
- let idx =
84
- Pconst_integer (string_of_int (i + 1), None)
85
- |> Exp.constant
86
- in
87
- [%expr Belt.Array.getExn json_arr [%e idx]] );
88
- ])
89
- |> tuple_or_singleton Exp.tuple)
90
-
91
- let generate_decoder_case generator_settings
92
- { pcd_name = { txt = name }; pcd_args; pcd_loc } =
93
- match pcd_args with
94
- | Pcstr_tuple args ->
95
- let arg_len =
96
- Pconst_integer (string_of_int (List.length args + 1), None)
97
- |> Exp.constant
98
- in
99
- let decoded =
100
- match args with
101
- | [] ->
102
- let ident = lid name in
103
- [%expr Belt.Result.Ok [%e Exp.construct ident None]]
104
- | _ -> generate_arg_decoder generator_settings args name
105
- in
106
-
107
- {
108
- pc_lhs =
109
- ( Pconst_string (name, Location.none, None) |> Pat.constant |> fun v ->
110
- Some v |> Pat.construct (lid "Js.Json.JSONString") );
111
- pc_guard = None;
112
- pc_rhs =
113
- [%expr
114
- if Js.Array.length tagged <> [%e arg_len] then
115
- Spice.error "Invalid number of arguments to variant constructor" v
116
- else [%e decoded]];
117
- }
118
- | Pcstr_record _ -> fail pcd_loc "This syntax is not yet implemented by spice"
119
-
120
- let generate_decoder_case_attr generator_settings
121
- { name; alias; constr_decl = { pcd_args; pcd_loc } } =
122
- match pcd_args with
123
- | Pcstr_tuple args ->
124
- let alias_name, _, delimit = get_string_from_expression alias in
125
- let decoded =
126
- match args with
127
- | [] ->
128
- let ident = lid name in
129
- [%expr Belt.Result.Ok [%e Exp.construct ident None]]
130
- | _ -> generate_arg_decoder generator_settings args name
131
- in
132
-
133
- let if' =
134
- Exp.apply (make_ident_expr "=")
135
- [
136
- ( Asttypes.Nolabel,
137
- Pconst_string (alias_name, Location.none, delimit) |> Exp.constant
138
- );
139
- (Asttypes.Nolabel, [%expr str]);
140
- ]
141
- in
142
- let then' = [%expr [%e decoded]] in
143
-
144
- (if', then')
145
- | Pcstr_record _ -> fail pcd_loc "This syntax is not yet implemented by spice"
146
-
147
- let generate_unboxed_decode generator_settings
148
- { pcd_name = { txt = name }; pcd_args; pcd_loc } =
149
- match pcd_args with
150
- | Pcstr_tuple args -> (
151
- match args with
152
- | [ a ] -> (
153
- let _, d = Codecs.generate_codecs generator_settings a in
154
- match d with
155
- | Some d ->
156
- let constructor = Exp.construct (lid name) (Some [%expr v]) in
157
-
158
- Some
159
- [%expr
160
- fun v ->
161
- Belt.Result.map ([%e d] v) (fun v -> [%e constructor])]
162
- | None -> None)
163
- | _ -> fail pcd_loc "Expected exactly one type argument")
164
- | Pcstr_record _ -> fail pcd_loc "This syntax is not yet implemented by spice"
165
-
166
- let parse_decl _generator_settings
167
- ({ pcd_name = { txt }; pcd_loc; pcd_attributes } as constr_decl) =
168
- let alias, has_attr_as =
169
- match get_attribute_by_name pcd_attributes "spice.as" with
170
- | Ok (Some attribute) -> (get_expression_from_payload attribute, true)
171
- | Ok None -> (Exp.constant (Pconst_string (txt, Location.none, None)), false)
172
- | Error s -> (fail pcd_loc s, false)
173
- in
174
-
175
- { name = txt; alias; has_attr_as; constr_decl }
176
-
177
- let generate_codecs ({ do_encode; do_decode } as generator_settings)
178
- constr_decls unboxed =
179
- let parsed_decls = List.map (parse_decl generator_settings) constr_decls in
180
- let count_has_attr =
181
- parsed_decls |> List.filter (fun v -> v.has_attr_as) |> List.length
182
- in
183
- let has_attr_as =
184
- if count_has_attr > 0 then
185
- if count_has_attr = List.length parsed_decls then true
186
- else failwith "Partial @spice.as usage is not allowed"
187
- else false
188
- in
189
-
190
- let encoder =
191
- some_if_true do_encode
192
- (parsed_decls
193
- |> List.map (generate_encoder_case generator_settings unboxed has_attr_as)
194
- |> Exp.match_ [%expr v]
195
- |> Exp.fun_ Asttypes.Nolabel None [%pat? v])
196
- in
197
-
198
- let decoder =
199
- match not do_decode with
200
- | true -> None
201
- | false ->
202
- if unboxed then
203
- generate_unboxed_decode generator_settings (List.hd constr_decls)
204
- else if has_attr_as then
205
- let rec make_ifthenelse cases =
206
- match cases with
207
- | [] -> [%expr Spice.error "Not matched" v]
208
- | hd :: tl ->
209
- let if_, then_ = hd in
210
- Exp.ifthenelse if_ then_ (Some (make_ifthenelse tl))
211
- in
212
-
213
- let decoder_switch =
214
- List.map
215
- (generate_decoder_case_attr generator_settings)
216
- parsed_decls
217
- |> make_ifthenelse
218
- in
219
-
220
- Some
221
- [%expr
222
- fun v ->
223
- match Js.Json.classify v with
224
- | Js.Json.JSONString str -> [%e decoder_switch]
225
- | _ -> Spice.error "Not a JSONString" v]
226
- else
227
- let decoder_default_case =
228
- {
229
- pc_lhs = [%pat? _];
230
- pc_guard = None;
231
- pc_rhs =
232
- [%expr
233
- Spice.error "Invalid variant constructor"
234
- (Belt.Array.getExn json_arr 0)];
235
- }
236
- in
237
-
238
- let decoder_switch =
239
- constr_decls |> List.map (generate_decoder_case generator_settings)
240
- |> fun l ->
241
- l @ [ decoder_default_case ]
242
- |> Exp.match_ [%expr Belt.Array.getExn tagged 0]
243
- in
244
-
245
- Some
246
- [%expr
247
- fun v ->
248
- match Js.Json.classify v with
249
- | Js.Json.JSONArray [||] ->
250
- Spice.error "Expected variant, found empty array" v
251
- | Js.Json.JSONArray json_arr ->
252
- let tagged = Js.Array.map Js.Json.classify json_arr in
253
- [%e decoder_switch]
254
- | _ -> Spice.error "Not a variant" v]
255
- in
256
-
257
- (encoder, decoder)
@@ -1,21 +0,0 @@
1
- opam-version: "2.0"
2
- name: "ppx_spice"
3
- version: "0.1.8"
4
- synopsis: "ReScript PPX which generate JSON (de)serializer"
5
- description: """
6
- ReScript PPX which generate JSON (de)serializer
7
- """
8
- maintainer: "Greenlabs Dev <developer@greenlabs.co.kr>"
9
- authors: "Greenlabs Dev <developer@greenlabs.co.kr>"
10
- license: "MIT"
11
- homepage: "https://github.com/green-labs/ppx_spice"
12
- bug-reports: "https://github.com/green-labs/ppx_spice/issues"
13
- dev-repo: "git+https://github.com/green-labs/ppx_spice.git"
14
- depends: [
15
- "ocaml" { = "4.12.1"}
16
- "dune" { >= "2.7"}
17
- "ppxlib" { = "0.23.0"}
18
- ]
19
- build: [
20
- ["dune" "build" "-p" name "-j" jobs]
21
- ]
@@ -1,91 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
- 'use strict';
3
-
4
- var Jest = require("@glennsl/bs-jest/src/jest.js");
5
- var OptionalFieldRecords = require("../src/OptionalFieldRecords.js");
6
-
7
- Jest.describe("optional field record", (function (param) {
8
- var sample = {};
9
- sample["a"] = 1;
10
- sample["b"] = 1;
11
- var sampleRecord = {
12
- a: 1,
13
- b: 1
14
- };
15
- Jest.test("encode", (function (param) {
16
- var encoded = OptionalFieldRecords.t0_encode(sampleRecord);
17
- return Jest.Expect.toEqual(sample, Jest.Expect.expect(encoded));
18
- }));
19
- Jest.test("decode", (function (param) {
20
- var decoded = OptionalFieldRecords.t0_decode(sample);
21
- return Jest.Expect.toEqual({
22
- TAG: /* Ok */0,
23
- _0: sampleRecord
24
- }, Jest.Expect.expect(decoded));
25
- }));
26
- }));
27
-
28
- Jest.describe("optional field record: array<int>", (function (param) {
29
- var sample = {};
30
- sample["a"] = 1;
31
- sample["bs"] = [1];
32
- var sampleRecord_bs = [1];
33
- var sampleRecord = {
34
- a: 1,
35
- bs: sampleRecord_bs
36
- };
37
- Jest.test("encode", (function (param) {
38
- var encoded = OptionalFieldRecords.t1_encode(sampleRecord);
39
- return Jest.Expect.toEqual(sample, Jest.Expect.expect(encoded));
40
- }));
41
- Jest.test("decode", (function (param) {
42
- var decoded = OptionalFieldRecords.t1_decode(sample);
43
- return Jest.Expect.toEqual({
44
- TAG: /* Ok */0,
45
- _0: sampleRecord
46
- }, Jest.Expect.expect(decoded));
47
- }));
48
- }));
49
-
50
- Jest.describe("optional field record: array<variant>", (function (param) {
51
- var sample = {};
52
- sample["a"] = 1;
53
- sample["bs"] = ["B1"];
54
- var sampleRecord_bs = [/* B1 */1];
55
- var sampleRecord = {
56
- a: 1,
57
- bs: sampleRecord_bs
58
- };
59
- Jest.test("encode", (function (param) {
60
- var encoded = OptionalFieldRecords.t2_encode(sampleRecord);
61
- return Jest.Expect.toEqual(sample, Jest.Expect.expect(encoded));
62
- }));
63
- Jest.test("decode", (function (param) {
64
- var decoded = OptionalFieldRecords.t2_decode(sample);
65
- return Jest.Expect.toEqual({
66
- TAG: /* Ok */0,
67
- _0: sampleRecord
68
- }, Jest.Expect.expect(decoded));
69
- }));
70
- }));
71
-
72
- Jest.describe("optional field record: omit array<variant>", (function (param) {
73
- var sample = {};
74
- sample["a"] = 1;
75
- var sampleRecord = {
76
- a: 1
77
- };
78
- Jest.test("encode", (function (param) {
79
- var encoded = OptionalFieldRecords.t2_encode(sampleRecord);
80
- return Jest.Expect.toEqual(sample, Jest.Expect.expect(encoded));
81
- }));
82
- Jest.test("decode", (function (param) {
83
- var decoded = OptionalFieldRecords.t2_decode(sample);
84
- return Jest.Expect.toEqual({
85
- TAG: /* Ok */0,
86
- _0: sampleRecord
87
- }, Jest.Expect.expect(decoded));
88
- }));
89
- }));
90
-
91
- /* Not a pure module */
@@ -1,98 +0,0 @@
1
- open Jest
2
- open Expect
3
- // open Belt
4
-
5
- describe("optional field record", _ => {
6
- open OptionalFieldRecords
7
-
8
- let sample = Js.Dict.empty()
9
- sample->Js.Dict.set("a", Js.Json.number(1.))
10
- sample->Js.Dict.set("b", Js.Json.number(1.))
11
- let sampleJson = sample->Js.Json.object_
12
-
13
- let sampleRecord: t0 = {
14
- a: 1,
15
- b: 1,
16
- }
17
-
18
- test(`encode`, _ => {
19
- let encoded = sampleRecord->t0_encode
20
- expect(encoded) |> toEqual(sampleJson)
21
- })
22
-
23
- test(`decode`, _ => {
24
- let decoded = sampleJson->t0_decode
25
- expect(decoded) |> toEqual(Belt.Result.Ok(sampleRecord))
26
- })
27
- })
28
-
29
- describe("optional field record: array<int>", _ => {
30
- open OptionalFieldRecords
31
-
32
- let sample = Js.Dict.empty()
33
- sample->Js.Dict.set("a", Js.Json.number(1.))
34
- sample->Js.Dict.set("bs", Js.Json.array([Js.Json.number(1.)]))
35
- let sampleJson = sample->Js.Json.object_
36
-
37
- let sampleRecord: t1 = {
38
- a: 1,
39
- bs: [1],
40
- }
41
-
42
- test(`encode`, _ => {
43
- let encoded = sampleRecord->t1_encode
44
- expect(encoded) |> toEqual(sampleJson)
45
- })
46
-
47
- test(`decode`, _ => {
48
- let decoded = sampleJson->t1_decode
49
- expect(decoded) |> toEqual(Belt.Result.Ok(sampleRecord))
50
- })
51
- })
52
-
53
- describe("optional field record: array<variant>", _ => {
54
- open OptionalFieldRecords
55
-
56
- let sample = Js.Dict.empty()
57
- sample->Js.Dict.set("a", Js.Json.number(1.))
58
- sample->Js.Dict.set("bs", Js.Json.array([Js.Json.string("B1")]))
59
- let sampleJson = sample->Js.Json.object_
60
-
61
- let sampleRecord: t2 = {
62
- a: 1,
63
- bs: [B1],
64
- }
65
-
66
- test(`encode`, _ => {
67
- let encoded = sampleRecord->t2_encode
68
- expect(encoded) |> toEqual(sampleJson)
69
- })
70
-
71
- test(`decode`, _ => {
72
- let decoded = sampleJson->t2_decode
73
- expect(decoded) |> toEqual(Belt.Result.Ok(sampleRecord))
74
- })
75
- })
76
-
77
- describe("optional field record: omit array<variant>", _ => {
78
- open OptionalFieldRecords
79
-
80
- let sample = Js.Dict.empty()
81
- sample->Js.Dict.set("a", Js.Json.number(1.))
82
-
83
- let sampleJson = sample->Js.Json.object_
84
-
85
- let sampleRecord: t2 = {
86
- a: 1,
87
- }
88
-
89
- test(`encode`, _ => {
90
- let encoded = sampleRecord->t2_encode
91
- expect(encoded) |> toEqual(sampleJson)
92
- })
93
-
94
- test(`decode`, _ => {
95
- let decoded = sampleJson->t2_decode
96
- expect(decoded) |> toEqual(Belt.Result.Ok(sampleRecord))
97
- })
98
- })