@greenlabs/ppx-spice 0.1.6-rc3 → 0.1.7-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.
@@ -0,0 +1,6 @@
1
+ {
2
+ "ocaml.sandbox": {
3
+ "kind": "opam",
4
+ "switch": "4.12.1"
5
+ }
6
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # CHANGELOG
2
+
3
+ # 0.1.7
4
+
5
+ #### :rocket: New Feature
6
+
7
+ - Add support for the optional field record
package/README.md CHANGED
@@ -3,10 +3,11 @@
3
3
  A ReScript PPX, which generates JSON (de)serializers.
4
4
 
5
5
  `Spice` is originated from
6
- * The `Spice melange` in the novel, Dune
7
- * A flavor for the (polymorphic) variant
8
6
 
9
- > This PPX is highly influenced by [Decco](https://github.com/reasonml-labs/decco) and developed with forking the source codes of Decco. Spice has implemented all the features of Decco@1.5.0 and additional useful features for (polymorphic) variant of its own.
7
+ - The `Spice melange` in the novel, Dune
8
+ - A flavor for the (polymorphic) variant
9
+
10
+ > This PPX is highly influenced by [Decco](https://github.com/reasonml-labs/decco) and developed with forking the source codes of Decco. Spice has implemented all the features of Decco@1.5.0 and additional useful features for the (polymorphic) variant of its own.
10
11
 
11
12
  ## Motivation
12
13
 
@@ -14,6 +15,61 @@ A ReScript PPX, which generates JSON (de)serializers.
14
15
 
15
16
  To parse the JSON data, [Decco](https://github.com/reasonml-labs/decco) is being heavily used in many projects. But, there's a restriction to parse the JSON string into a (polymorphic) variant with the Decco. The JSON data should be formed in an array. It is obvious at some point. But generally, we face the string data which needs to be parsed into the variant in most use cases.
16
17
 
18
+ Whenever it is needed to parse the response in Json, the custom encoder/decoder functions are needed to parse the Json string into the (polymorphic) variant with Decco. But you don't need to write it with the Spice as long as you add `@spice.as` in (polymorphic) variants.
19
+
20
+ with Decco
21
+
22
+ ```rescript
23
+ @decco
24
+ type status = WAITING | PROCESSING | SUCCESS | FAIL
25
+
26
+ let encoderStatus = v =>
27
+ switch v {
28
+ | WAITING => "waiting"
29
+ | PROCESSING => "processing"
30
+ | SUCCESS => "success"
31
+ | FAIL => "fail"
32
+ }->Js.Json.string
33
+
34
+ let decoderStatus = json => {
35
+ switch json |> Js.Json.classify {
36
+ | Js.Json.JSONString(str) =>
37
+ switch str {
38
+ | "waiting" => WAITING->Ok
39
+ | "processing" => PROCESSING->Ok
40
+ | "success" => SUCCESS->Ok
41
+ | "fail" => FAIL->Ok
42
+ | _ => Error({Decco.path: "", message: "Expected JSONString", value: json})
43
+ }
44
+ | _ => Error({Decco.path: "", message: "Expected JSONString", value: json})
45
+ }
46
+ }
47
+
48
+ let codecStatus: Decco.codec<status> = (encoderStatus, decoderStatus)
49
+
50
+
51
+ @decco
52
+ type data = {
53
+ status: @decco.codec(codecStatus) status,
54
+ }
55
+ ```
56
+
57
+ with Spice
58
+
59
+ ```rescript
60
+ @spice
61
+ type status =
62
+ | @spice.as("waiting") WAITING
63
+ | @spice.as("processing") PROCESSING
64
+ | @spice.as("success") SUCCESS
65
+ | @spice.as("fail") FAIL
66
+
67
+ @spice
68
+ type data = {
69
+ status: status,
70
+ }
71
+ ```
72
+
17
73
  2. Parse/stringify the Unicode string
18
74
 
19
75
  There are many cases to parse and stringify the string data into (polymorphic) variants. Furthermore, the Unicode string needs to be handled with a variant. Currently, pattern matching is not working for the Unicode string in ReScript, the Spice is using `if ... then ... else` to compare the Unicode string in case of adding `@spice.as` attribute.
@@ -32,7 +88,7 @@ let t_encode = ...
32
88
  // automatically generated
33
89
  let t_decode = ...
34
90
 
35
- let encoded = One->t_encode // Js.Json.JSONString(`하나`)
91
+ let encoded = One->t_encode // Js.Json.string(`하나`)
36
92
 
37
93
  let decoded = Js.Json.string(`second`)->t_decode // Belt.Result.Ok(Two)
38
94
  ```
@@ -64,12 +120,16 @@ let decoded = sampleJson->Records.t_decode // Belt.Result.Ok(sampleRecord)
64
120
 
65
121
  ## Install
66
122
 
67
- ```
123
+ ```sh
68
124
  yarn add -D @greenlabs/ppx-spice
69
125
  ```
70
126
 
71
- ```
127
+ ```json
72
128
  // bsconfig.json
129
+
130
+ "bs-dependencies": [
131
+ "@greenlabs/ppx-spice"
132
+ ],
73
133
  "ppx-flags": [
74
134
  ...,
75
135
  "@greenlabs/ppx-spice/ppx"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@greenlabs/ppx-spice",
3
- "version": "0.1.6-rc3",
4
- "description": "ReScript PPX which generate the (polymorphic) variant (de)serializer",
3
+ "version": "0.1.7-rc1",
4
+ "description": "ReScript PPX which generate JSON (de)serializer",
5
5
  "license": "MIT",
6
6
  "author": "Greenlabs Dev <developer@greenlabs.co.kr>",
7
7
  "repository": {
package/ppx-linux.exe CHANGED
Binary file
package/ppx-osx.exe CHANGED
Binary file
package/src/ppx/codecs.ml CHANGED
@@ -27,165 +27,103 @@ and generate_constr_codecs { do_encode; do_decode }
27
27
  { Location.txt = identifier; loc } =
28
28
  let open Longident in
29
29
  match identifier with
30
- | Lident "string" -> (
31
- ( (match do_encode with
32
- | true -> Some [%expr Spice.stringToJson]
33
- | false -> None),
34
- match do_decode with
35
- | true -> Some [%expr Spice.stringFromJson]
36
- | false -> None ))
37
- | Lident "int" -> (
38
- ( (match do_encode with
39
- | true -> Some [%expr Spice.intToJson]
40
- | false -> None),
41
- match do_decode with
42
- | true -> Some [%expr Spice.intFromJson]
43
- | false -> None ))
44
- | Lident "int64" -> (
45
- ( (match do_encode with
46
- | true -> Some [%expr Spice.int64ToJson]
47
- | false -> None),
48
- match do_decode with
49
- | true -> Some [%expr Spice.int64FromJson]
50
- | false -> None ))
51
- | Lident "float" -> (
52
- ( (match do_encode with
53
- | true -> Some [%expr Spice.floatToJson]
54
- | false -> None),
55
- match do_decode with
56
- | true -> Some [%expr Spice.floatFromJson]
57
- | false -> None ))
58
- | Lident "bool" -> (
59
- ( (match do_encode with
60
- | true -> Some [%expr Spice.boolToJson]
61
- | false -> None),
62
- match do_decode with
63
- | true -> Some [%expr Spice.boolFromJson]
64
- | false -> None ))
65
- | Lident "unit" -> (
66
- ( (match do_encode with
67
- | true -> Some [%expr Spice.unitToJson]
68
- | false -> None),
69
- match do_decode with
70
- | true -> Some [%expr Spice.unitFromJson]
71
- | false -> None ))
72
- | Lident "array" -> (
73
- ( (match do_encode with
74
- | true -> Some [%expr Spice.arrayToJson]
75
- | false -> None),
76
- match do_decode with
77
- | true -> Some [%expr Spice.arrayFromJson]
78
- | false -> None ))
79
- | Lident "list" -> (
80
- ( (match do_encode with
81
- | true -> Some [%expr Spice.listToJson]
82
- | false -> None),
83
- match do_decode with
84
- | true -> Some [%expr Spice.listFromJson]
85
- | false -> None ))
86
- | Lident "option" -> (
87
- ( (match do_encode with
88
- | true -> Some [%expr Spice.optionToJson]
89
- | false -> None),
90
- match do_decode with
91
- | true -> Some [%expr Spice.optionFromJson]
92
- | false -> None ))
93
- | Ldot (Ldot (Lident "Belt", "Result"), "t") -> (
94
- ( (match do_encode with
95
- | true -> Some [%expr Spice.resultToJson]
96
- | false -> None),
97
- match do_decode with
98
- | true -> Some [%expr Spice.resultFromJson]
99
- | false -> None ))
100
- | Ldot (Ldot (Lident "Js", "Dict"), "t") -> (
101
- ( (match do_encode with
102
- | true -> Some [%expr Spice.dictToJson]
103
- | false -> None),
104
- match do_decode with
105
- | true -> Some [%expr Spice.dictFromJson]
106
- | false -> None ))
107
- | Ldot (Ldot (Lident "Js", "Json"), "t") -> (
108
- ( (match do_encode with true -> Some [%expr fun v -> v] | false -> None),
109
- match do_decode with
110
- | true -> Some [%expr fun v -> Belt.Result.Ok v]
111
- | false -> None ))
112
- | Lident s -> (
113
- ( (match do_encode with
114
- | true -> Some (make_ident_expr (s ^ Utils.encoder_func_suffix))
115
- | false -> None),
116
- match do_decode with
117
- | true -> Some (make_ident_expr (s ^ Utils.decoder_func_suffix))
118
- | false -> None ))
119
- | Ldot (left, right) -> (
120
- ( (match do_encode with
121
- | true ->
122
- Some
123
- (Exp.ident
124
- (mknoloc (Ldot (left, right ^ Utils.encoder_func_suffix))))
125
- | false -> None),
126
- match do_decode with
127
- | true ->
128
- Some
129
- (Exp.ident
130
- (mknoloc (Ldot (left, right ^ Utils.decoder_func_suffix))))
131
- | false -> None ))
30
+ | Lident "string" ->
31
+ ( some_if_true do_encode [%expr Spice.stringToJson],
32
+ some_if_true do_decode [%expr Spice.stringFromJson] )
33
+ | Lident "int" ->
34
+ ( some_if_true do_encode [%expr Spice.intToJson],
35
+ some_if_true do_decode [%expr Spice.intFromJson] )
36
+ | Lident "int64" ->
37
+ ( some_if_true do_encode [%expr Spice.int64ToJson],
38
+ some_if_true do_decode [%expr Spice.int64FromJson] )
39
+ | Lident "float" ->
40
+ ( some_if_true do_encode [%expr Spice.floatToJson],
41
+ some_if_true do_decode [%expr Spice.floatFromJson] )
42
+ | Lident "bool" ->
43
+ ( some_if_true do_encode [%expr Spice.boolToJson],
44
+ some_if_true do_decode [%expr Spice.boolFromJson] )
45
+ | Lident "unit" ->
46
+ ( some_if_true do_encode [%expr Spice.unitToJson],
47
+ some_if_true do_decode [%expr Spice.unitFromJson] )
48
+ | Lident "array" ->
49
+ ( some_if_true do_encode [%expr Spice.arrayToJson],
50
+ some_if_true do_decode [%expr Spice.arrayFromJson] )
51
+ | Lident "list" ->
52
+ ( some_if_true do_encode [%expr Spice.listToJson],
53
+ some_if_true do_decode [%expr Spice.listFromJson] )
54
+ | Lident "option" ->
55
+ ( some_if_true do_encode [%expr Spice.optionToJson],
56
+ some_if_true do_decode [%expr Spice.optionFromJson] )
57
+ | Ldot (Ldot (Lident "Belt", "Result"), "t") ->
58
+ ( some_if_true do_encode [%expr Spice.resultToJson],
59
+ some_if_true do_decode [%expr Spice.resultFromJson] )
60
+ | Ldot (Ldot (Lident "Js", "Dict"), "t") ->
61
+ ( some_if_true do_encode [%expr Spice.dictToJson],
62
+ some_if_true do_decode [%expr Spice.dictFromJson] )
63
+ | Ldot (Ldot (Lident "Js", "Json"), "t") ->
64
+ ( some_if_true do_encode [%expr fun v -> v],
65
+ some_if_true do_decode [%expr fun v -> Belt.Result.Ok v] )
66
+ | Lident s ->
67
+ ( some_if_true do_encode (make_ident_expr (s ^ Utils.encoder_func_suffix)),
68
+ some_if_true do_decode (make_ident_expr (s ^ Utils.decoder_func_suffix))
69
+ )
70
+ | Ldot (left, right) ->
71
+ ( some_if_true do_encode
72
+ (Exp.ident (mknoloc (Ldot (left, right ^ Utils.encoder_func_suffix)))),
73
+ some_if_true do_decode
74
+ (Exp.ident (mknoloc (Ldot (left, right ^ Utils.decoder_func_suffix))))
75
+ )
132
76
  | Lapply (_, _) -> fail loc "Lapply syntax not yet handled by spice"
133
77
 
134
- and generate_codecs ({ do_encode; do_decode } as generator_settings)
78
+ and generate_codecs ?(is_optional = false)
79
+ ({ do_encode; do_decode } as generator_settings)
135
80
  { ptyp_desc; ptyp_loc; ptyp_attributes } =
136
81
  match ptyp_desc with
137
82
  | Ptyp_any -> fail ptyp_loc "Can't generate codecs for `any` type"
138
83
  | Ptyp_arrow (_, _, _) ->
139
84
  fail ptyp_loc "Can't generate codecs for function type"
140
85
  | Ptyp_package _ -> fail ptyp_loc "Can't generate codecs for module type"
141
- | Ptyp_tuple types -> (
86
+ | Ptyp_tuple types ->
142
87
  let composite_codecs =
143
- List.map (generate_codecs generator_settings) types
88
+ List.map (generate_codecs ~is_optional generator_settings) types
144
89
  in
145
- ( (match do_encode with
146
- | true ->
147
- Some
148
- (composite_codecs
149
- |> List.map (fun (e, _) -> Option.get e)
150
- |> Tuple.generate_encoder)
151
- | false -> None),
152
- match do_decode with
153
- | true ->
154
- Some
155
- (composite_codecs
156
- |> List.map (fun (_, d) -> Option.get d)
157
- |> Tuple.generate_decoder)
158
- | false -> None ))
159
- | Ptyp_var s -> (
160
- ( (match do_encode with
161
- | true -> Some (make_ident_expr (encoder_var_prefix ^ s))
162
- | false -> None),
163
- match do_decode with
164
- | true -> Some (make_ident_expr (decoder_var_prefix ^ s))
165
- | false -> None ))
90
+ ( some_if_true do_encode
91
+ (composite_codecs
92
+ |> List.map (fun (e, _) -> Option.get e)
93
+ |> Tuple.generate_encoder),
94
+ some_if_true do_decode
95
+ (composite_codecs
96
+ |> List.map (fun (_, d) -> Option.get d)
97
+ |> Tuple.generate_decoder) )
98
+ | Ptyp_var s ->
99
+ ( some_if_true do_encode (make_ident_expr (encoder_var_prefix ^ s)),
100
+ some_if_true do_decode (make_ident_expr (decoder_var_prefix ^ s)) )
166
101
  | Ptyp_constr (constr, typeArgs) -> (
167
102
  let custom_codec = get_attribute_by_name ptyp_attributes "spice.codec" in
168
103
  let encode, decode =
169
104
  match custom_codec with
170
105
  | Ok None -> generate_constr_codecs generator_settings constr
171
- | Ok (Some attribute) -> (
106
+ | Ok (Some attribute) ->
172
107
  let expr = get_expression_from_payload attribute in
173
- ( (match do_encode with
174
- | true ->
175
- Some
176
- [%expr
177
- let e, _ = [%e expr] in
178
- e]
179
- | false -> None),
180
- match do_decode with
181
- | true ->
182
- Some
183
- [%expr
184
- let _, d = [%e expr] in
185
- d]
186
- | false -> None ))
108
+ ( some_if_true do_encode
109
+ [%expr
110
+ let e, _ = [%e expr] in
111
+ e],
112
+ some_if_true do_decode
113
+ [%expr
114
+ let _, d = [%e expr] in
115
+ d] )
187
116
  | Error s -> fail ptyp_loc s
188
117
  in
118
+ let encode, decode =
119
+ if is_optional then
120
+ match (encode, decode) with
121
+ | Some encode, Some decode ->
122
+ ( Some [%expr Spice.optionToJson [%e encode]],
123
+ Some [%expr Spice.optionFromJson [%e decode]] )
124
+ | _ -> (encode, decode)
125
+ else (encode, decode)
126
+ in
189
127
  match List.length typeArgs = 0 with
190
128
  | true -> (encode, decode)
191
129
  | false -> parameterize_codecs typeArgs encode decode generator_settings)
@@ -219,15 +219,12 @@ let generate_codecs ({ do_encode; do_decode } as generator_settings) row_fields
219
219
  in
220
220
 
221
221
  let encoder =
222
- match do_encode with
223
- | true ->
224
- List.map
225
- (generate_encoder_case generator_settings unboxed has_attr_as)
226
- parsed_fields
227
- |> Exp.match_ [%expr v]
228
- |> Exp.fun_ Asttypes.Nolabel None [%pat? v]
229
- |> Option.some
230
- | false -> None
222
+ some_if_true do_encode
223
+ (List.map
224
+ (generate_encoder_case generator_settings unboxed has_attr_as)
225
+ parsed_fields
226
+ |> Exp.match_ [%expr v]
227
+ |> Exp.fun_ Asttypes.Nolabel None [%pat? v])
231
228
  in
232
229
 
233
230
  let decoder =
@@ -11,8 +11,16 @@ type parsed_decl = {
11
11
  field : expression;
12
12
  codecs : expression option * expression option;
13
13
  default : expression option;
14
+ is_optional : bool;
14
15
  }
15
16
 
17
+ let optional_attr : Ppxlib.Parsetree.attribute =
18
+ {
19
+ attr_name = { txt = "ns.optional"; loc = Location.none };
20
+ attr_payload = PStr [];
21
+ attr_loc = Location.none;
22
+ }
23
+
16
24
  let generate_encoder decls unboxed =
17
25
  match unboxed with
18
26
  | true ->
@@ -22,11 +30,17 @@ let generate_encoder decls unboxed =
22
30
  | false ->
23
31
  let arrExpr =
24
32
  decls
25
- |> List.map (fun { key; field; codecs = encoder, _ } ->
26
- [%expr [%e key], [%e Option.get encoder] [%e field]])
33
+ |> List.map (fun { key; field; codecs = encoder, _; is_optional } ->
34
+ let is_optional =
35
+ if is_optional then [%expr true] else [%expr false]
36
+ in
37
+ [%expr
38
+ [%e key], [%e is_optional], [%e Option.get encoder] [%e field]])
27
39
  |> Exp.array
28
40
  in
29
- [%expr [%e arrExpr] |> Js.Dict.fromArray |> Js.Json.object_]
41
+ [%expr
42
+ [%e arrExpr] |> Spice.filterOptional |> Js.Dict.fromArray
43
+ |> Js.Json.object_]
30
44
  |> Exp.fun_ Asttypes.Nolabel None [%pat? v]
31
45
 
32
46
  let generate_dict_get { key; codecs = _, decoder; default } =
@@ -53,7 +67,10 @@ let generate_error_case { key } =
53
67
  }
54
68
 
55
69
  let generate_final_record_expr decls =
56
- decls |> List.map (fun { name } -> (lid name, make_ident_expr name))
70
+ decls
71
+ |> List.map (fun { name; is_optional } ->
72
+ let attrs = if is_optional then [ optional_attr ] else [] in
73
+ (lid name, make_ident_expr ~attrs name))
57
74
  |> fun l -> [%expr Belt.Result.Ok [%e Exp.record l None]]
58
75
 
59
76
  let generate_success_case { name } success_expr =
@@ -113,20 +130,24 @@ let parse_decl generator_settings
113
130
  | Ok None -> Exp.constant (Pconst_string (txt, Location.none, None))
114
131
  | Error s -> fail pld_loc s
115
132
  in
133
+ let optional_attrs = [ "ns.optional"; "res.optional" ] in
134
+ let is_optional =
135
+ optional_attrs
136
+ |> List.map (fun attr -> get_attribute_by_name pld_attributes attr)
137
+ |> List.exists (function Ok (Some _) -> true | _ -> false)
138
+ in
139
+
116
140
  {
117
141
  name = txt;
118
142
  key;
119
143
  field = Exp.field [%expr v] (lid txt);
120
- codecs = Codecs.generate_codecs generator_settings pld_type;
144
+ codecs = Codecs.generate_codecs ~is_optional generator_settings pld_type;
121
145
  default;
146
+ is_optional;
122
147
  }
123
148
 
124
149
  let generate_codecs ({ do_encode; do_decode } as generator_settings) decls
125
150
  unboxed =
126
151
  let parsed_decls = List.map (parse_decl generator_settings) decls in
127
- ( (match do_encode with
128
- | true -> Some (generate_encoder parsed_decls unboxed)
129
- | false -> None),
130
- match do_decode with
131
- | true -> Some (generate_decoder parsed_decls unboxed)
132
- | false -> None )
152
+ ( some_if_true do_encode (generate_encoder parsed_decls unboxed),
153
+ some_if_true do_decode (generate_decoder parsed_decls unboxed) )
package/src/ppx/utils.ml CHANGED
@@ -24,7 +24,7 @@ let mknoloc txt = mkloc txt Location.none
24
24
 
25
25
  let lid ?(loc = Location.none) s = mkloc (Longident.parse s) loc
26
26
 
27
- let make_ident_expr s = Exp.ident (mknoloc (longident_parse s))
27
+ let make_ident_expr ?attrs s = Exp.ident ?attrs (mknoloc (longident_parse s))
28
28
 
29
29
  let tuple_or_singleton tuple l =
30
30
  match List.length l > 1 with true -> tuple l | false -> List.hd l
@@ -113,3 +113,5 @@ let attr_warning expr =
113
113
  attr_payload = PStr [ { pstr_desc = Pstr_eval (expr, []); pstr_loc = loc } ];
114
114
  attr_loc = loc;
115
115
  }
116
+
117
+ let some_if_true cond a = match cond with true -> Some a | false -> None
@@ -188,15 +188,11 @@ let generate_codecs ({ do_encode; do_decode } as generator_settings)
188
188
  in
189
189
 
190
190
  let encoder =
191
- match do_encode with
192
- | true ->
193
- parsed_decls
194
- |> List.map
195
- (generate_encoder_case generator_settings unboxed has_attr_as)
196
- |> Exp.match_ [%expr v]
197
- |> Exp.fun_ Asttypes.Nolabel None [%pat? v]
198
- |> Option.some
199
- | false -> None
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])
200
196
  in
201
197
 
202
198
  let decoder =
@@ -0,0 +1,21 @@
1
+ opam-version: "2.0"
2
+ name: "ppx_spice"
3
+ version: "0.1.7"
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
+ ]
@@ -14,7 +14,7 @@ let error = (~path=?, message, value) => {
14
14
  | None => ""
15
15
  | Some(s) => s
16
16
  }
17
- Belt.Result.Error({path: path, message: message, value: value})
17
+ Belt.Result.Error({path, message, value})
18
18
  }
19
19
 
20
20
  let stringToJson = s => Js.Json.string(s)
@@ -98,6 +98,11 @@ let optionToJson = (encoder, opt) =>
98
98
  | None => Js.Json.null
99
99
  }
100
100
 
101
+ let filterOptional = arr =>
102
+ arr
103
+ |> Belt.Array.keep(_, ((_, isOptional, x)) => !(isOptional && x == Js.Json.null))
104
+ |> Belt.Array.map(_, ((k, _, v)) => (k, v))
105
+
101
106
  let optionFromJson = (decoder, json) =>
102
107
  switch Js.Json.decodeNull(json) {
103
108
  | Some(_) => Belt.Result.Ok(None)
@@ -5,28 +5,28 @@ var Jest = require("@glennsl/bs-jest/src/jest.js");
5
5
  var Polyvariants = require("../src/Polyvariants.js");
6
6
 
7
7
  Jest.describe("polymorphic variants with attribute", (function (param) {
8
- Jest.test("encode \xed\x95\x98\xeb\x82\x98", (function (param) {
8
+ Jest.test("encode 하나", (function (param) {
9
9
  var polyvariantEncoded = Polyvariants.t_encode("one");
10
10
  return Jest.Expect.toEqual("하나", Jest.Expect.expect(polyvariantEncoded));
11
11
  }));
12
- Jest.test("encode \xeb\x91\x98", (function (param) {
12
+ Jest.test("encode ", (function (param) {
13
13
  var polyvariantEncoded = Polyvariants.t_encode("two");
14
14
  return Jest.Expect.toEqual("둘", Jest.Expect.expect(polyvariantEncoded));
15
15
  }));
16
- Jest.test("decode \xed\x95\x98\xeb\x82\x98", (function (param) {
16
+ Jest.test("decode 하나", (function (param) {
17
17
  var polyvariantDecoded = Polyvariants.t_decode("하나");
18
18
  return Jest.Expect.toEqual({
19
19
  TAG: /* Ok */0,
20
20
  _0: "one"
21
21
  }, Jest.Expect.expect(polyvariantDecoded));
22
22
  }));
23
- return Jest.test("decode \xeb\x91\x98", (function (param) {
24
- var polyvariantDecoded = Polyvariants.t_decode("둘");
25
- return Jest.Expect.toEqual({
26
- TAG: /* Ok */0,
27
- _0: "two"
28
- }, Jest.Expect.expect(polyvariantDecoded));
29
- }));
23
+ Jest.test("decode ", (function (param) {
24
+ var polyvariantDecoded = Polyvariants.t_decode("둘");
25
+ return Jest.Expect.toEqual({
26
+ TAG: /* Ok */0,
27
+ _0: "two"
28
+ }, Jest.Expect.expect(polyvariantDecoded));
29
+ }));
30
30
  }));
31
31
 
32
32
  Jest.describe("polymorphic variants", (function (param) {
@@ -45,13 +45,13 @@ Jest.describe("polymorphic variants", (function (param) {
45
45
  _0: "one"
46
46
  }, Jest.Expect.expect(polyvariantDecoded));
47
47
  }));
48
- return Jest.test("decode two", (function (param) {
49
- var polyvariantDecoded = Polyvariants.t1_decode(["two"]);
50
- return Jest.Expect.toEqual({
51
- TAG: /* Ok */0,
52
- _0: "two"
53
- }, Jest.Expect.expect(polyvariantDecoded));
54
- }));
48
+ Jest.test("decode two", (function (param) {
49
+ var polyvariantDecoded = Polyvariants.t1_decode(["two"]);
50
+ return Jest.Expect.toEqual({
51
+ TAG: /* Ok */0,
52
+ _0: "two"
53
+ }, Jest.Expect.expect(polyvariantDecoded));
54
+ }));
55
55
  }));
56
56
 
57
57
  /* Not a pure module */
@@ -16,13 +16,13 @@ Jest.describe("record with @spice.key", (function (param) {
16
16
  var encoded = Records.t_encode(sampleRecord);
17
17
  return Jest.Expect.toEqual(sample, Jest.Expect.expect(encoded));
18
18
  }));
19
- return Jest.test("decode", (function (param) {
20
- var decoded = Records.t_decode(sample);
21
- return Jest.Expect.toEqual({
22
- TAG: /* Ok */0,
23
- _0: sampleRecord
24
- }, Jest.Expect.expect(decoded));
25
- }));
19
+ Jest.test("decode", (function (param) {
20
+ var decoded = Records.t_decode(sample);
21
+ return Jest.Expect.toEqual({
22
+ TAG: /* Ok */0,
23
+ _0: sampleRecord
24
+ }, Jest.Expect.expect(decoded));
25
+ }));
26
26
  }));
27
27
 
28
28
  Jest.describe("record without @spice.key", (function (param) {
@@ -37,13 +37,64 @@ Jest.describe("record without @spice.key", (function (param) {
37
37
  var encoded = Records.t1_encode(sampleRecord);
38
38
  return Jest.Expect.toEqual(sample, Jest.Expect.expect(encoded));
39
39
  }));
40
- return Jest.test("decode", (function (param) {
41
- var decoded = Records.t1_decode(sample);
42
- return Jest.Expect.toEqual({
43
- TAG: /* Ok */0,
44
- _0: sampleRecord
45
- }, Jest.Expect.expect(decoded));
46
- }));
40
+ Jest.test("decode", (function (param) {
41
+ var decoded = Records.t1_decode(sample);
42
+ return Jest.Expect.toEqual({
43
+ TAG: /* Ok */0,
44
+ _0: sampleRecord
45
+ }, Jest.Expect.expect(decoded));
46
+ }));
47
+ }));
48
+
49
+ Jest.describe("record with optional field", (function (param) {
50
+ var sample1 = {};
51
+ sample1["label"] = "sample";
52
+ sample1["value"] = 1.0;
53
+ var sampleRecord1 = {
54
+ label: "sample",
55
+ value: 1
56
+ };
57
+ Jest.test("encode", (function (param) {
58
+ var encoded = Records.tOp_encode(sampleRecord1);
59
+ return Jest.Expect.toEqual(sample1, Jest.Expect.expect(encoded));
60
+ }));
61
+ Jest.test("decode", (function (param) {
62
+ var decoded = Records.tOp_decode(sample1);
63
+ return Jest.Expect.toEqual({
64
+ TAG: /* Ok */0,
65
+ _0: sampleRecord1
66
+ }, Jest.Expect.expect(decoded));
67
+ }));
68
+ var sample2 = {};
69
+ sample2["label"] = "sample";
70
+ var sampleRecord2 = {
71
+ label: "sample"
72
+ };
73
+ Jest.test("encode omit optional field", (function (param) {
74
+ var encoded = Records.tOp_encode(sampleRecord2);
75
+ return Jest.Expect.toEqual(sample2, Jest.Expect.expect(encoded));
76
+ }));
77
+ Jest.test("decode omit optional field", (function (param) {
78
+ var decoded = Records.tOp_decode(sample2);
79
+ return Jest.Expect.toEqual({
80
+ TAG: /* Ok */0,
81
+ _0: sampleRecord2
82
+ }, Jest.Expect.expect(decoded));
83
+ }));
84
+ var sample3 = {};
85
+ sample3["label"] = null;
86
+ var sampleRecord3 = {};
87
+ Jest.test("encode omit optional field with None field", (function (param) {
88
+ var encoded = Records.tOp_encode(sampleRecord3);
89
+ return Jest.Expect.toEqual(sample3, Jest.Expect.expect(encoded));
90
+ }));
91
+ Jest.test("decode omit optional field with None field", (function (param) {
92
+ var decoded = Records.tOp_decode(sample3);
93
+ return Jest.Expect.toEqual({
94
+ TAG: /* Ok */0,
95
+ _0: sampleRecord3
96
+ }, Jest.Expect.expect(decoded));
97
+ }));
47
98
  }));
48
99
 
49
100
  /* Not a pure module */
@@ -49,3 +49,63 @@ describe("record without @spice.key", _ => {
49
49
  expect(decoded) |> toEqual(Belt.Result.Ok(sampleRecord))
50
50
  })
51
51
  })
52
+
53
+ describe("record with optional field", _ => {
54
+ open Records
55
+
56
+ let sample1 = Js.Dict.empty()
57
+ sample1->Js.Dict.set("label", Js.Json.string("sample"))
58
+ sample1->Js.Dict.set("value", Js.Json.number(1.0))
59
+ let sampleJson1 = sample1->Js.Json.object_
60
+
61
+ let sampleRecord1: tOp = {
62
+ label: Some("sample"),
63
+ value: 1,
64
+ }
65
+
66
+ test(`encode`, _ => {
67
+ let encoded = sampleRecord1->tOp_encode
68
+ expect(encoded) |> toEqual(sampleJson1)
69
+ })
70
+
71
+ test(`decode`, _ => {
72
+ let decoded = sampleJson1->Records.tOp_decode
73
+ expect(decoded) |> toEqual(Belt.Result.Ok(sampleRecord1))
74
+ })
75
+
76
+ let sample2 = Js.Dict.empty()
77
+ sample2->Js.Dict.set("label", Js.Json.string("sample"))
78
+ let sampleJson2 = sample2->Js.Json.object_
79
+
80
+ let sampleRecord2: tOp = {
81
+ label: Some("sample"),
82
+ }
83
+
84
+ test(`encode omit optional field`, _ => {
85
+ let encoded = sampleRecord2->tOp_encode
86
+ expect(encoded) |> toEqual(sampleJson2)
87
+ })
88
+
89
+ test(`decode omit optional field`, _ => {
90
+ let decoded = sampleJson2->Records.tOp_decode
91
+ expect(decoded) |> toEqual(Belt.Result.Ok(sampleRecord2))
92
+ })
93
+
94
+ let sample3 = Js.Dict.empty()
95
+ sample3->Js.Dict.set("label", Js.Json.null)
96
+ let sampleJson3 = sample3->Js.Json.object_
97
+
98
+ let sampleRecord3: tOp = {
99
+ label: None,
100
+ }
101
+
102
+ test(`encode omit optional field with None field`, _ => {
103
+ let encoded = sampleRecord3->tOp_encode
104
+ expect(encoded) |> toEqual(sampleJson3)
105
+ })
106
+
107
+ test(`decode omit optional field with None field`, _ => {
108
+ let decoded = sampleJson3->Records.tOp_decode
109
+ expect(decoded) |> toEqual(Belt.Result.Ok(sampleRecord3))
110
+ })
111
+ })
@@ -20,13 +20,13 @@ Jest.describe("variants with @spice.as", (function (param) {
20
20
  _0: /* One */0
21
21
  }, Jest.Expect.expect(variantDecoded));
22
22
  }));
23
- return Jest.test("decode 둘", (function (param) {
24
- var variantDecoded = Variants.t_decode("둘");
25
- return Jest.Expect.toEqual({
26
- TAG: /* Ok */0,
27
- _0: /* Two */1
28
- }, Jest.Expect.expect(variantDecoded));
29
- }));
23
+ Jest.test("decode 둘", (function (param) {
24
+ var variantDecoded = Variants.t_decode("둘");
25
+ return Jest.Expect.toEqual({
26
+ TAG: /* Ok */0,
27
+ _0: /* Two */1
28
+ }, Jest.Expect.expect(variantDecoded));
29
+ }));
30
30
  }));
31
31
 
32
32
  Jest.describe("variants without @spice.as", (function (param) {
@@ -45,13 +45,13 @@ Jest.describe("variants without @spice.as", (function (param) {
45
45
  _0: /* One1 */0
46
46
  }, Jest.Expect.expect(variantDecoded));
47
47
  }));
48
- return Jest.test("decode [\"Two1\"]", (function (param) {
49
- var variantDecoded = Variants.t1_decode(["Two1"]);
50
- return Jest.Expect.toEqual({
51
- TAG: /* Ok */0,
52
- _0: /* Two1 */1
53
- }, Jest.Expect.expect(variantDecoded));
54
- }));
48
+ Jest.test("decode [\"Two1\"]", (function (param) {
49
+ var variantDecoded = Variants.t1_decode(["Two1"]);
50
+ return Jest.Expect.toEqual({
51
+ TAG: /* Ok */0,
52
+ _0: /* Two1 */1
53
+ }, Jest.Expect.expect(variantDecoded));
54
+ }));
55
55
  }));
56
56
 
57
57
  Jest.describe("unboxed variants with @spice.as", (function (param) {
@@ -59,13 +59,13 @@ Jest.describe("unboxed variants with @spice.as", (function (param) {
59
59
  var variantEncoded = Variants.t2_encode(0);
60
60
  return Jest.Expect.toEqual(0.0, Jest.Expect.expect(variantEncoded));
61
61
  }));
62
- return Jest.test("decode 하나", (function (param) {
63
- var variantDecoded = Variants.t2_decode(0.0);
64
- return Jest.Expect.toEqual({
65
- TAG: /* Ok */0,
66
- _0: 0
67
- }, Jest.Expect.expect(variantDecoded));
68
- }));
62
+ Jest.test("decode 하나", (function (param) {
63
+ var variantDecoded = Variants.t2_decode(0.0);
64
+ return Jest.Expect.toEqual({
65
+ TAG: /* Ok */0,
66
+ _0: 0
67
+ }, Jest.Expect.expect(variantDecoded));
68
+ }));
69
69
  }));
70
70
 
71
71
  Jest.describe("unboxed variants without @spice.as", (function (param) {
@@ -73,13 +73,13 @@ Jest.describe("unboxed variants without @spice.as", (function (param) {
73
73
  var variantEncoded = Variants.t3_encode(0);
74
74
  return Jest.Expect.toEqual(0.0, Jest.Expect.expect(variantEncoded));
75
75
  }));
76
- return Jest.test("decode 0", (function (param) {
77
- var variantDecoded = Variants.t3_decode(0.0);
78
- return Jest.Expect.toEqual({
79
- TAG: /* Ok */0,
80
- _0: 0
81
- }, Jest.Expect.expect(variantDecoded));
82
- }));
76
+ Jest.test("decode 0", (function (param) {
77
+ var variantDecoded = Variants.t3_decode(0.0);
78
+ return Jest.Expect.toEqual({
79
+ TAG: /* Ok */0,
80
+ _0: 0
81
+ }, Jest.Expect.expect(variantDecoded));
82
+ }));
83
83
  }));
84
84
 
85
85
  /* Not a pure module */
package/test/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "devDependencies": {
7
7
  "@glennsl/bs-jest": "^0.7.0",
8
8
  "jest": "^27.3.1",
9
- "rescript": "^9.1.4"
9
+ "rescript": "^10.0.1"
10
10
  },
11
11
  "scripts": {
12
12
  "res:build": "rescript",
@@ -3,6 +3,7 @@
3
3
 
4
4
  var Spice = require("./Spice.js");
5
5
  var Js_json = require("rescript/lib/js/js_json.js");
6
+ var Js_array = require("rescript/lib/js/js_array.js");
6
7
  var Belt_Array = require("rescript/lib/js/belt_Array.js");
7
8
 
8
9
  function t_encode(v) {
@@ -57,7 +58,7 @@ function t1_decode(v) {
57
58
  if (json_arr$1.length === 0) {
58
59
  return Spice.error(undefined, "Expected polyvariant, found empty array", v);
59
60
  }
60
- var tagged = json_arr$1.map(Js_json.classify);
61
+ var tagged = Js_array.map(Js_json.classify, json_arr$1);
61
62
  var match = Belt_Array.getExn(tagged, 0);
62
63
  if (typeof match !== "number" && match.TAG === /* JSONString */0) {
63
64
  switch (match._0) {
@@ -7,16 +7,18 @@ var Js_json = require("rescript/lib/js/js_json.js");
7
7
  var Belt_Option = require("rescript/lib/js/belt_Option.js");
8
8
 
9
9
  function t_encode(v) {
10
- return Js_dict.fromArray([
11
- [
12
- "spice-label",
13
- Spice.stringToJson(v.label)
14
- ],
15
- [
16
- "spice-value",
17
- Spice.intToJson(v.value)
18
- ]
19
- ]);
10
+ return Js_dict.fromArray(Spice.filterOptional([
11
+ [
12
+ "spice-label",
13
+ false,
14
+ Spice.stringToJson(v.label)
15
+ ],
16
+ [
17
+ "spice-value",
18
+ false,
19
+ Spice.intToJson(v.value)
20
+ ]
21
+ ]));
20
22
  }
21
23
 
22
24
  function t_decode(v) {
@@ -62,16 +64,18 @@ function t_decode(v) {
62
64
  }
63
65
 
64
66
  function t1_encode(v) {
65
- return Js_dict.fromArray([
66
- [
67
- "label",
68
- Spice.stringToJson(v.label)
69
- ],
70
- [
71
- "value",
72
- Spice.intToJson(v.value)
73
- ]
74
- ]);
67
+ return Js_dict.fromArray(Spice.filterOptional([
68
+ [
69
+ "label",
70
+ false,
71
+ Spice.stringToJson(v.label)
72
+ ],
73
+ [
74
+ "value",
75
+ false,
76
+ Spice.intToJson(v.value)
77
+ ]
78
+ ]));
75
79
  }
76
80
 
77
81
  function t1_decode(v) {
@@ -116,8 +120,67 @@ function t1_decode(v) {
116
120
  };
117
121
  }
118
122
 
123
+ function tOp_encode(v) {
124
+ return Js_dict.fromArray(Spice.filterOptional([
125
+ [
126
+ "label",
127
+ false,
128
+ Spice.optionToJson(Spice.stringToJson, v.label)
129
+ ],
130
+ [
131
+ "value",
132
+ true,
133
+ Spice.optionToJson(Spice.intToJson, v.value)
134
+ ]
135
+ ]));
136
+ }
137
+
138
+ function tOp_decode(v) {
139
+ var dict = Js_json.classify(v);
140
+ if (typeof dict === "number") {
141
+ return Spice.error(undefined, "Not an object", v);
142
+ }
143
+ if (dict.TAG !== /* JSONObject */2) {
144
+ return Spice.error(undefined, "Not an object", v);
145
+ }
146
+ var dict$1 = dict._0;
147
+ var label = Spice.optionFromJson(Spice.stringFromJson, Belt_Option.getWithDefault(Js_dict.get(dict$1, "label"), null));
148
+ if (label.TAG === /* Ok */0) {
149
+ var value = Spice.optionFromJson(Spice.intFromJson, Belt_Option.getWithDefault(Js_dict.get(dict$1, "value"), null));
150
+ if (value.TAG === /* Ok */0) {
151
+ return {
152
+ TAG: /* Ok */0,
153
+ _0: {
154
+ label: label._0,
155
+ value: value._0
156
+ }
157
+ };
158
+ }
159
+ var e = value._0;
160
+ return {
161
+ TAG: /* Error */1,
162
+ _0: {
163
+ path: ".value" + e.path,
164
+ message: e.message,
165
+ value: e.value
166
+ }
167
+ };
168
+ }
169
+ var e$1 = label._0;
170
+ return {
171
+ TAG: /* Error */1,
172
+ _0: {
173
+ path: ".label" + e$1.path,
174
+ message: e$1.message,
175
+ value: e$1.value
176
+ }
177
+ };
178
+ }
179
+
119
180
  exports.t_encode = t_encode;
120
181
  exports.t_decode = t_decode;
121
182
  exports.t1_encode = t1_encode;
122
183
  exports.t1_decode = t1_decode;
184
+ exports.tOp_encode = tOp_encode;
185
+ exports.tOp_decode = tOp_decode;
123
186
  /* No side effect */
@@ -9,3 +9,9 @@ type t1 = {
9
9
  label: string,
10
10
  value: int,
11
11
  }
12
+
13
+ @spice
14
+ type tOp = {
15
+ label: option<string>,
16
+ value?: int,
17
+ }
@@ -9,3 +9,9 @@ type t1 = {
9
9
  label: string,
10
10
  value: int,
11
11
  }
12
+
13
+ @spice
14
+ type tOp = {
15
+ label: option<string>,
16
+ value?: int,
17
+ }
package/test/src/Spice.js CHANGED
@@ -6,6 +6,8 @@ var Curry = require("rescript/lib/js/curry.js");
6
6
  var Js_dict = require("rescript/lib/js/js_dict.js");
7
7
  var Js_json = require("rescript/lib/js/js_json.js");
8
8
  var Js_math = require("rescript/lib/js/js_math.js");
9
+ var Caml_obj = require("rescript/lib/js/caml_obj.js");
10
+ var Js_array = require("rescript/lib/js/js_array.js");
9
11
  var Belt_Array = require("rescript/lib/js/belt_Array.js");
10
12
  var Caml_int64 = require("rescript/lib/js/caml_int64.js");
11
13
  var Belt_Result = require("rescript/lib/js/belt_Result.js");
@@ -166,14 +168,12 @@ function unitFromJson(param) {
166
168
  };
167
169
  }
168
170
 
169
- function arrayToJson(encoder, arr) {
170
- return arr.map(Curry.__1(encoder));
171
- }
171
+ var arrayToJson = Js_array.map;
172
172
 
173
173
  function arrayFromJson(decoder, json) {
174
174
  var arr = Js_json.decodeArray(json);
175
175
  if (arr !== undefined) {
176
- return arr.reduce((function (acc, jsonI, i) {
176
+ return Js_array.reducei((function (acc, jsonI, i) {
177
177
  var match = Curry._1(decoder, jsonI);
178
178
  if (acc.TAG !== /* Ok */0) {
179
179
  return acc;
@@ -181,7 +181,7 @@ function arrayFromJson(decoder, json) {
181
181
  if (match.TAG === /* Ok */0) {
182
182
  return {
183
183
  TAG: /* Ok */0,
184
- _0: acc._0.concat([match._0])
184
+ _0: Js_array.concat([match._0], acc._0)
185
185
  };
186
186
  }
187
187
  var error = match._0;
@@ -196,7 +196,7 @@ function arrayFromJson(decoder, json) {
196
196
  }), {
197
197
  TAG: /* Ok */0,
198
198
  _0: []
199
- });
199
+ }, arr);
200
200
  } else {
201
201
  return {
202
202
  TAG: /* Error */1,
@@ -211,7 +211,7 @@ function arrayFromJson(decoder, json) {
211
211
 
212
212
  function listToJson(encoder, list) {
213
213
  var arr = $$Array.of_list(list);
214
- return arr.map(Curry.__1(encoder));
214
+ return Js_array.map(encoder, arr);
215
215
  }
216
216
 
217
217
  function listFromJson(decoder, json) {
@@ -227,6 +227,18 @@ function optionToJson(encoder, opt) {
227
227
  }
228
228
  }
229
229
 
230
+ function filterOptional(arr) {
231
+ var __x = Belt_Array.keep(arr, (function (param) {
232
+ return !(param[1] && Caml_obj.equal(param[2], null));
233
+ }));
234
+ return Belt_Array.map(__x, (function (param) {
235
+ return [
236
+ param[0],
237
+ param[2]
238
+ ];
239
+ }));
240
+ }
241
+
230
242
  function optionFromJson(decoder, json) {
231
243
  var match = Js_json.decodeNull(json);
232
244
  if (match !== undefined) {
@@ -426,6 +438,7 @@ exports.arrayFromJson = arrayFromJson;
426
438
  exports.listToJson = listToJson;
427
439
  exports.listFromJson = listFromJson;
428
440
  exports.optionToJson = optionToJson;
441
+ exports.filterOptional = filterOptional;
429
442
  exports.optionFromJson = optionFromJson;
430
443
  exports.resultToJson = resultToJson;
431
444
  exports.resultFromJson = resultFromJson;
@@ -3,6 +3,7 @@
3
3
 
4
4
  var Spice = require("./Spice.js");
5
5
  var Js_json = require("rescript/lib/js/js_json.js");
6
+ var Js_array = require("rescript/lib/js/js_array.js");
6
7
  var Belt_Array = require("rescript/lib/js/belt_Array.js");
7
8
  var Belt_Result = require("rescript/lib/js/belt_Result.js");
8
9
 
@@ -58,7 +59,7 @@ function t1_decode(v) {
58
59
  if (json_arr$1.length === 0) {
59
60
  return Spice.error(undefined, "Expected variant, found empty array", v);
60
61
  }
61
- var tagged = json_arr$1.map(Js_json.classify);
62
+ var tagged = Js_array.map(Js_json.classify, json_arr$1);
62
63
  var match = Belt_Array.getExn(tagged, 0);
63
64
  if (typeof match !== "number" && match.TAG === /* JSONString */0) {
64
65
  switch (match._0) {
package/test/yarn.lock CHANGED
@@ -3466,10 +3466,10 @@ require-main-filename@^2.0.0:
3466
3466
  resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
3467
3467
  integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
3468
3468
 
3469
- rescript@^9.1.4:
3470
- version "9.1.4"
3471
- resolved "https://registry.yarnpkg.com/rescript/-/rescript-9.1.4.tgz#1eb126f98d6c16942c0bf0df67c050198e580515"
3472
- integrity sha512-aXANK4IqecJzdnDpJUsU6pxMViCR5ogAxzuqS0mOr8TloMnzAjJFu63fjD6LCkWrKAhlMkFFzQvVQYaAaVkFXw==
3469
+ rescript@^10.0.1:
3470
+ version "10.0.1"
3471
+ resolved "https://registry.yarnpkg.com/rescript/-/rescript-10.0.1.tgz#5b2da8a8bcfb994bed1eb24820bf10cfb9d8c440"
3472
+ integrity sha512-XwO1GPDtoEU4H03xQE5bp0/qtSVR6YLaJRPxWKrfFgKc+LI36ODOCie7o9UJfgzQdoMYkkZyiTGZ4N9OQEaiUw==
3473
3473
 
3474
3474
  resolve-cwd@^3.0.0:
3475
3475
  version "3.0.0"
@@ -1,43 +0,0 @@
1
- lib: [
2
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/META"
3
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/dune-package"
4
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/opam"
5
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/polyvariants.ml"
6
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice.a"
7
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice.cma"
8
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice.cmi"
9
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice.cmt"
10
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice.cmx"
11
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice.cmxa"
12
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice.ml"
13
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__.cmi"
14
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__.cmt"
15
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__.cmx"
16
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__.ml"
17
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Polyvariants.cmi"
18
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Polyvariants.cmt"
19
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Polyvariants.cmx"
20
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Signature.cmi"
21
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Signature.cmt"
22
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Signature.cmx"
23
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Structure.cmi"
24
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Structure.cmt"
25
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Structure.cmx"
26
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Utils.cmi"
27
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Utils.cmt"
28
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Utils.cmx"
29
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Variants.cmi"
30
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Variants.cmt"
31
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice__Variants.cmx"
32
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/signature.ml"
33
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/structure.ml"
34
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/utils.ml"
35
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/variants.ml"
36
- ]
37
- libexec: [
38
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx.exe"
39
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/lib/ppx_spice/ppx_spice.cmxs"
40
- ]
41
- bin: [
42
- "/Users/woonki/Documents/projects/ppx_spice/src/_esy/default/store/b/ppx__spice-dc255e86/install/default/bin/ppx_spice"
43
- ]