Skip to content

Commit 9540042

Browse files
committed
fix: use Exp.ifthenelse instead of Exp.match_ due to unicode
- Currently, due to the pattern matching with unicode issue, use the ifthenelse. - It is planned to release the built-in unicode encode for source. rescript-lang/syntax#433 - As soon as the new built-in feature is released, will change to use pattern matching again.
1 parent e4e48bf commit 9540042

File tree

8 files changed

+88
-86
lines changed

8 files changed

+88
-86
lines changed

src/ppx/polyvariants.ml

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,24 @@ let generateDecoderCase generatorSettings row =
3434
let { name; alias; rowField = { prf_desc } } = row in
3535
match prf_desc with
3636
| Rtag ({ txt; loc }, _, coreTypes) ->
37+
let alias_name, loc, delimit = getStringFromExpression alias in
3738
let decoded =
3839
let resultantExp = Exp.variant txt None in
3940
[%expr Belt.Result.Ok [%e resultantExp]]
4041
in
4142

42-
let alias_name, loc, delimit = getStringFromExpression alias in
43+
let if' =
44+
Exp.apply (makeIdentExpr "=")
45+
[
46+
( Asttypes.Nolabel,
47+
Pconst_string (alias_name, Location.none, delimit) |> Exp.constant
48+
|> fun v -> Some v |> Exp.construct (lid "Js.Json.JSONString") );
49+
(Asttypes.Nolabel, [%expr tagged]);
50+
]
51+
in
52+
let then' = [%expr [%e decoded]] in
4353

44-
{
45-
pc_lhs =
46-
( Pconst_string (alias_name, Location.none, delimit) |> Pat.constant
47-
|> fun v -> Some v |> Pat.construct (lid "Js.Json.JSONString") );
48-
pc_guard = None;
49-
pc_rhs = [%expr [%e decoded]];
50-
}
54+
(if', then')
5155
| Rinherit coreType ->
5256
fail coreType.ptyp_loc "This syntax is not yet implemented by decco"
5357

@@ -101,13 +105,14 @@ let generateCodecs ({ doEncode; doDecode } as generatorSettings) rowFields
101105
| false -> None
102106
in
103107

104-
let decoderDefaultCase =
105-
{
106-
pc_lhs = [%pat? _];
107-
pc_guard = None;
108-
pc_rhs = [%expr Decco.error "Invalid polyvariant constructor" v];
109-
}
108+
let rec makeIfThenElse cases =
109+
match cases with
110+
| [] -> [%expr Decco.error "Not matched" v]
111+
| hd :: tl ->
112+
let if_, then_ = hd in
113+
Exp.ifthenelse if_ then_ (Some (makeIfThenElse tl))
110114
in
115+
111116
let decoder =
112117
match not doDecode with
113118
| true -> None
@@ -117,9 +122,9 @@ let generateCodecs ({ doEncode; doDecode } as generatorSettings) rowFields
117122
| false ->
118123
let decoderSwitch =
119124
List.map (generateDecoderCase generatorSettings) parsedFields
120-
|> fun l ->
121-
l @ [ decoderDefaultCase ] |> Exp.match_ [%expr tagged]
125+
|> makeIfThenElse
122126
in
127+
123128
Some
124129
[%expr
125130
fun v ->
@@ -129,4 +134,5 @@ let generateCodecs ({ doEncode; doDecode } as generatorSettings) rowFields
129134
[%e decoderSwitch]
130135
| _ -> Decco.error "Not a polyvariant" v])
131136
in
137+
132138
(encoder, decoder)

src/ppx/variants.ml

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,24 @@ let generateEncoderCase generatorSettings
2424

2525
let generateDecoderCase generatorSettings
2626
{ name; alias; constrDecl = { pcd_args; pcd_loc } } =
27+
let alias_name, _, delimit = getStringFromExpression alias in
2728
let decoded =
2829
let ident = lid name in
2930
[%expr Belt.Result.Ok [%e Exp.construct ident None]]
3031
in
3132

32-
let alias_name, _, delimit = getStringFromExpression alias in
33+
let if' =
34+
Exp.apply (makeIdentExpr "=")
35+
[
36+
( Asttypes.Nolabel,
37+
Pconst_string (alias_name, Location.none, delimit) |> Exp.constant
38+
|> fun v -> Some v |> Exp.construct (lid "Js.Json.JSONString") );
39+
(Asttypes.Nolabel, [%expr tagged]);
40+
]
41+
in
42+
let then' = [%expr [%e decoded]] in
3343

34-
{
35-
pc_lhs =
36-
( Pconst_string (alias_name, Location.none, delimit) |> Pat.constant
37-
|> fun v -> Some v |> Pat.construct (lid "Js.Json.JSONString") );
38-
pc_guard = None;
39-
pc_rhs = [%expr [%e decoded]];
40-
}
44+
(if', then')
4145

4246
let generateUnboxedDecode generatorSettings
4347
{ pcd_name = { txt = name }; pcd_args; pcd_loc } =
@@ -81,12 +85,12 @@ let generateCodecs ({ doEncode; doDecode } as generatorSettings) constrDecls
8185
| false -> None
8286
in
8387

84-
let decoderDefaultCase =
85-
{
86-
pc_lhs = [%pat? _];
87-
pc_guard = None;
88-
pc_rhs = [%expr Decco.error "Invalid variant constructor" v];
89-
}
88+
let rec makeIfThenElse cases =
89+
match cases with
90+
| [] -> [%expr Decco.error "Not matched" v]
91+
| hd :: tl ->
92+
let if_, then_ = hd in
93+
Exp.ifthenelse if_ then_ (Some (makeIfThenElse tl))
9094
in
9195

9296
let decoder =
@@ -98,8 +102,7 @@ let generateCodecs ({ doEncode; doDecode } as generatorSettings) constrDecls
98102
| false ->
99103
let decoderSwitch =
100104
List.map (generateDecoderCase generatorSettings) parsedDecls
101-
|> fun l ->
102-
l @ [ decoderDefaultCase ] |> Exp.match_ [%expr tagged]
105+
|> makeIfThenElse
103106
in
104107

105108
Some

test/__tests__/test.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/__tests__/test.res

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ open Expect
55
describe("ppx_spice test", _ => {
66
test("polymorphic variant encode", _ => {
77
let sample1Encoded = #one->Sample1.t_encode
8-
expect(sample1Encoded) |> toEqual("first"->Js.Json.string)
8+
expect(sample1Encoded) |> toEqual(`하나`->Js.Json.string)
99
})
1010
test("polymorphic variant decode", _ => {
11-
let sample1Decoded = "second"->Js.Json.string->Sample1.t_decode
11+
let sample1Decoded = `둘`->Js.Json.string->Sample1.t_decode
1212
expect(sample1Decoded) |> toEqual(Ok(#two))
1313
})
1414

@@ -17,7 +17,7 @@ describe("ppx_spice test", _ => {
1717
expect(sample2Encoded) |> toEqual(`하나`->Js.Json.string)
1818
})
1919
test("variant decode", _ => {
20-
let sample2Decoded = "둘"->Js.Json.string->Sample2.t_decode
20+
let sample2Decoded = `둘`->Js.Json.string->Sample2.t_decode
2121
expect(sample2Decoded) |> toEqual(Ok(Sample2.Two))
2222
})
2323
})

test/src/sample1.js

Lines changed: 21 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/src/sample1.res

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
11
@spice
2-
type t = [@spice.as("first") #one | @spice.as("second") #two]
3-
4-
let sample1 = #one
2+
type t = [@spice.as(`하나`) #one | @spice.as(`둘`) #two]

test/src/sample1.resi

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
11
@spice
22
type t = [#one | #two]
3-
4-
let sample1: t

test/src/sample2.js

Lines changed: 19 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)