diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e7a032..9c4bf0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +# 0.1.11 + +- Add `@ppx_ts.toArray` feature for polymorphic variants + # 0.1.10 - Add `@ppx_ts.toArray` feature diff --git a/package.json b/package.json index 72a6857..a9e8272 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@greenlabs/ppx-ts", - "version": "0.1.10", + "version": "0.1.11", "description": "ReScript PPX helps binding to typescript modules", "license": "MIT", "author": "Greenlabs Dev ", diff --git a/ppx_ts.opam b/ppx_ts.opam index 0802f94..54ed3df 100644 --- a/ppx_ts.opam +++ b/ppx_ts.opam @@ -1,6 +1,6 @@ # This file is generated by dune, edit dune-project instead opam-version: "2.0" -version: "0.1.10" +version: "0.1.11" synopsis: "A PPX helps binding to typescript modules" description: "" maintainer: ["developer@greenlabs.co.kr"] diff --git a/rescript/__tests__/test.js b/rescript/__tests__/test.js index e456643..0dba17f 100644 --- a/rescript/__tests__/test.js +++ b/rescript/__tests__/test.js @@ -34,4 +34,19 @@ Jest.describe("toArray", (function (param) { })); })); +Jest.describe("Polyvari toArray", (function (param) { + Jest.test("check array length", (function (param) { + var length = View.t9_toArray.length; + return Jest.Expect.toEqual(2, Jest.Expect.expect(length)); + })); + Jest.test("The first item is 'Name'", (function (param) { + var first = View.t9_toArray[0]; + return Jest.Expect.toEqual("Name", Jest.Expect.expect(first)); + })); + return Jest.test("The second item is 'Age'", (function (param) { + var first = View.t9_toArray[1]; + return Jest.Expect.toEqual("Age", Jest.Expect.expect(first)); + })); + })); + /* Not a pure module */ diff --git a/rescript/__tests__/test.res b/rescript/__tests__/test.res index 077ac0c..a4f99c4 100644 --- a/rescript/__tests__/test.res +++ b/rescript/__tests__/test.res @@ -35,3 +35,20 @@ describe("toArray", _ => { expect(first) |> toEqual("Age") }) }) + +describe("Polyvari toArray", _ => { + test("check array length", _ => { + let length = View.t9_toArray->Array.length + expect(length) |> toEqual(2) + }) + + test("The first item is 'Name'", _ => { + let first = View.t9_toArray->Array.unsafe_get(0) + expect(first) |> toEqual("Name") + }) + + test("The second item is 'Age'", _ => { + let first = View.t9_toArray->Array.unsafe_get(1) + expect(first) |> toEqual("Age") + }) +}) diff --git a/rescript/src/View.js b/rescript/src/View.js index cc8600d..497ad0b 100644 --- a/rescript/src/View.js +++ b/rescript/src/View.js @@ -415,6 +415,11 @@ var t8_toArray = [ "Age" ]; +var t9_toArray = [ + "Name", + "Age" +]; + exports.Err = Err; exports.t_keyToString = t_keyToString; exports.t1_encode = t1_encode; @@ -430,4 +435,5 @@ exports.t4_decode = t4_decode; exports.t5_encode = t5_encode; exports.t5_decode = t5_decode; exports.t8_toArray = t8_toArray; +exports.t9_toArray = t9_toArray; /* No side effect */ diff --git a/rescript/src/View.res b/rescript/src/View.res index 96158c0..3bd4a8d 100644 --- a/rescript/src/View.res +++ b/rescript/src/View.res @@ -36,3 +36,6 @@ type t7 = %ppx_ts.partial(t) @ppx_ts.toArray type t8 = Name(string) | Age(int) + +@ppx_ts.toArray +type t9 = [#Name(string) | #Age(int)] diff --git a/rescript/src/View.resi b/rescript/src/View.resi index d9b4409..340e1e2 100644 --- a/rescript/src/View.resi +++ b/rescript/src/View.resi @@ -30,3 +30,6 @@ type t7 = %ppx_ts.partial(t) @ppx_ts.toArray type t8 = Name(string) | Age(int) + +@ppx_ts.toArray +type t9 = [#Name(string) | #Age(int)] diff --git a/src/sig_to_array.ml b/src/sig_to_array.ml index bb6bb60..2801bb2 100644 --- a/src/sig_to_array.ml +++ b/src/sig_to_array.ml @@ -5,25 +5,32 @@ open Utils (* keyOf attribute mapper *) let make_signature_items name loc manifest kind suffix = + let value_binding = + [ + Sig.value ~loc + (Val.mk + (mkloc (name ^ "_" ^ suffix) loc) + (Typ.constr (Utils.lid "array") + [ Typ.constr (Utils.lid "string") [] ])); + ] + in + match (manifest, kind) with - | None, Ptype_abstract -> fail loc "Can't handle the unspecified type" + | Some { ptyp_desc = Ptyp_variant (_, _, _) }, Ptype_abstract | None, Ptype_variant _ -> - [ - Sig.value ~loc - (Val.mk - (mkloc (name ^ "_" ^ suffix) loc) - (Typ.constr (Utils.lid "array") - [ Typ.constr (Utils.lid "string") [] ])); - ] + value_binding | _ -> fail loc "This type is not handled by ppx_ts" (* keyOf extension mapper *) let make_new_signature_item name loc manifest kind attributes = + let value_description = + Sig.value ~loc + (Val.mk ~loc ~attrs:attributes (mkloc name loc) + (Typ.constr (Utils.lid "array") [ Typ.constr (Utils.lid "string") [] ])) + in + match (manifest, kind) with - | None, Ptype_abstract -> fail loc "Can't handle the unspecified type" + | Some { ptyp_desc = Ptyp_variant (_, _, _) }, Ptype_abstract | None, Ptype_record _ -> - Sig.value ~loc - (Val.mk ~loc ~attrs:attributes (mkloc name loc) - (Typ.constr (Utils.lid "array") - [ Typ.constr (Utils.lid "string") [] ])) + value_description | _ -> fail loc "This type is not handled by ppx_ts" diff --git a/src/str_to_array.ml b/src/str_to_array.ml index e27aaa2..92bf8e1 100644 --- a/src/str_to_array.ml +++ b/src/str_to_array.ml @@ -5,43 +5,54 @@ open Utils (* toArray attribute mapper *) let make_structure_items name loc manifest kind suffix = - match (manifest, kind) with - (* type t *) - | None, Ptype_abstract -> fail loc "Can't handle the unspecified type" - | None, Ptype_variant cds -> - let keys = + let keys = + match (manifest, kind) with + (* type t *) + | Some { ptyp_desc = Ptyp_variant (row_fields, _, _) }, Ptype_abstract -> + row_fields + |> List.filter_map (fun { prf_desc; prf_loc = loc } -> + match prf_desc with + | Rtag ({ txt }, _, _) -> Some (txt, loc) + | Rinherit _ -> None) + | None, Ptype_variant cds -> cds |> List.map (fun { pcd_name = { txt }; pcd_loc } -> (txt, pcd_loc)) - in + | _ -> fail loc "This type is not handled by @ppx_ts.toArray" + in + [ + Str.value ~loc Nonrecursive [ - Str.value ~loc Nonrecursive - [ - Vb.mk - (Pat.var (mkloc (name ^ "_" ^ suffix) loc)) - (Exp.array - (keys - |> List.map (fun (key, loc) -> - Exp.constant (Pconst_string (key, loc, None))))); - ]; - ] - | _ -> fail loc "This type is not handled by @ppx_ts.toArray" + Vb.mk + (Pat.var (mkloc (name ^ "_" ^ suffix) loc)) + (Exp.array + (keys + |> List.map (fun (key, loc) -> + Exp.constant (Pconst_string (key, loc, None))))); + ]; + ] (* toArray extension mapper *) let make_new_structure_item name loc manifest kind attributes = - match (manifest, kind) with - (* type t *) - | None, Ptype_abstract -> fail loc "Can't handle the unspecified type" - | None, Ptype_variant cds -> - let keys = + let keys = + match (manifest, kind) with + (* type t *) + | Some { ptyp_desc = Ptyp_variant (row_fields, _, _) }, Ptype_abstract -> + row_fields + |> List.filter_map (fun { prf_desc; prf_loc = loc } -> + match prf_desc with + | Rtag ({ txt }, _, _) -> Some (txt, loc) + | Rinherit _ -> None) + | None, Ptype_variant cds -> cds |> List.map (fun { pcd_name = { txt }; pcd_loc } -> (txt, pcd_loc)) - in - Str.value ~loc Nonrecursive - [ - Vb.mk ~loc ~attrs:attributes - (Pat.var (mkloc name loc)) - (Exp.array - (keys - |> List.map (fun (key, loc) -> - Exp.constant (Pconst_string (key, loc, None))))); - ] - | _ -> fail loc "This type is not handled by %ppx_ts.toArray" + | _ -> fail loc "This type is not handled by %ppx_ts.toArray" + in + + Str.value ~loc Nonrecursive + [ + Vb.mk ~loc ~attrs:attributes + (Pat.var (mkloc name loc)) + (Exp.array + (keys + |> List.map (fun (key, loc) -> + Exp.constant (Pconst_string (key, loc, None))))); + ]