From 19fcb0911979f9ac37c1f0266c7929764d7fc46c Mon Sep 17 00:00:00 2001 From: Javier Chavarri Date: Fri, 16 Aug 2024 09:39:46 +0000 Subject: [PATCH] ppx: move readme content to main one, remove yojson refs --- README.md | 121 ++++++++++++++++++++++++++++++++++++++++++++++- ppx/README.md | 127 -------------------------------------------------- 2 files changed, 120 insertions(+), 128 deletions(-) delete mode 100644 ppx/README.md diff --git a/README.md b/README.md index 214860d..5ee96ec 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # melange-json -Compositional JSON encode/decode library for BuckleScript. +Compositional JSON encode/decode library and PPX for +[Melange](https://melange.re/). Based on [@glennsl/bs-json](https://github.com/glennsl/bs-json). @@ -146,6 +147,124 @@ let floatPoint = point(Json.Decode.float); Encoders work exactly the same way, just in reverse. `'a encoder` is just an alias for `'a -> Js.Json.t`, and this also transfers to composition: `'a encoder -> 'a array encoder` expands to `('a -> Js.Json.t) -> 'a array -> Js.Json.t`. +## PPX + +A [ppx deriver +plugin][https://ocaml.org/docs/metaprogramming#attributes-and-derivers] is +provided to automatically convert OCaml values to and from JSON. + +### Installation + +The PPX is included in the `melange-json` package. To use it, just add the +`dune` configuration to your project: + +```dune +(library + (modes melange) + (preprocess (pps melange-json.ppx))) +``` + +### Usage + +To generate JSON converters for a type, add the `[@@deriving json]` attribute to +a type declaration: + +```ocaml +type t = { + a: int; + b: string; +} [@@deriving json] +``` + +This will generate the following pair of functions: + +```ocaml +val of_json : Js.Json.t -> t +val to_json : t -> Js.Json.t +``` + +#### Generating JSON converters from type expressions + +You can also generate JSON converters for a type expression using the `to_json` +and `of_json` extension points: + +```ocaml +let json = [%to_json: int * string] (42, "foo") +``` + +#### Enumeration-like variants + +Note that variants where all constructors have no arguments are treated as +enumeration-like variants: + +```ocaml +type t = A | B [@@deriving json] +``` + +Such variants are represented as strings in JSON: + +```ocaml +let json = to_json A +(* json = `String "A" *) +``` + +#### `[@json.default E]`: default values for records + +You can specify default values for record fields using the `[@json.default E]` +attribute: + +```ocaml +type t = { + a: int; + b: string [@json.default "-"]; +} [@@deriving of_json] + +let t = of_json (`Assoc ["a", `Int 42]) +(* t = { a = 42; b = "-"; } *) +``` + +#### `[@json.option]`: a shortcut for `[@json.default None]` + +When a field has type `_ option` then you can use the `[@json.option]` attribute +to specify that the default value is `None`: + +```ocaml +type t = { + a: int; + b: string option [@json.option]; +} [@@deriving of_json] + +let t = of_json (`Assoc ["a", `Int 42]) +(* t = { a = 42; b = None; } *) +``` + +#### `[@json.key "S"]`: customizing keys for record fields + +You can specify custom keys for record fields using the `[@json.key E]` +attribute: + +```ocaml +type t = { + a: int [@json.key "A"]; + b: string [@json.key "B"]; +} [@@deriving of_json] + +let t = of_json (`Assoc ["A", `Int 42; "B", `String "foo"]) +(* t = { a = 42; b = "foo"; } *) +``` + +#### `[@json.as "S"]`: customizing the representation of a variant case + +You can specify custom representation for a variant case using the `[@json.as +E]` attribute: + +```ocaml +type t = A | B [@json.as "bbb"] [@@deriving json] + +let json = to_json B +(* json = `String "bbb" *) +``` + ## License This work is dual-licensed under LGPL 3.0 and MPL 2.0. diff --git a/ppx/README.md b/ppx/README.md deleted file mode 100644 index 9d93457..0000000 --- a/ppx/README.md +++ /dev/null @@ -1,127 +0,0 @@ -# PPX - -A [ppx deriver plugin][] for converting OCaml values to and from JSON. Works on -[melange][] (using `Js.Json.t` JSON representation). - -## Installation - -The PPX is included in `melange-json` package. To use it, just add the `dune` -configuration to your project: - -```dune -(library - (modes melange) - (preprocess (pps melange-json.ppx))) -``` - -## Usage - -To generate JSON converters for a type, add the `[@@deriving json]` attribute to -a type declaration: - -```ocaml -type t = { - a: int; - b: string; -} [@@deriving json] -``` - -This will generate the following pair of functions for native: - -```ocaml -val of_json : Yojson.Basic.json -> t -val to_json : t -> Yojson.Basic.json -``` - -and the following pair of functions for melange: - -```ocaml -val of_json : Js.Json.t -> t -val to_json : t -> Js.Json.t -``` - -### Generating JSON converters from type expressions - -You can also generate JSON converters for a type expression using the `to_json` -and `of_json` extension points: - -```ocaml -let json = [%to_json: int * string] (42, "foo") -``` - -### Enumeration-like variants - -Note that variants where all constructors have no arguments are treated as -enumeration-like variants: - -```ocaml -type t = A | B [@@deriving json] -``` - -Such variants are represented as strings in JSON: - -```ocaml -let json = to_json A -(* json = `String "A" *) -``` - -### `[@json.default E]`: default values for records - -You can specify default values for record fields using the `[@json.default E]` -attribute: - -```ocaml -type t = { - a: int; - b: string [@json.default "-"]; -} [@@deriving of_json] - -let t = of_json (`Assoc ["a", `Int 42]) -(* t = { a = 42; b = "-"; } *) -``` - -### `[@json.option]`: a shortcut for `[@json.default None]` - -When a field has type `_ option` then you can use the `[@json.option]` attribute -to specify that the default value is `None`: - -```ocaml -type t = { - a: int; - b: string option [@json.option]; -} [@@deriving of_json] - -let t = of_json (`Assoc ["a", `Int 42]) -(* t = { a = 42; b = None; } *) -``` - -### `[@json.key "S"]`: customizing keys for record fields - -You can specify custom keys for record fields using the `[@json.key E]` -attribute: - -```ocaml -type t = { - a: int [@json.key "A"]; - b: string [@json.key "B"]; -} [@@deriving of_json] - -let t = of_json (`Assoc ["A", `Int 42; "B", `String "foo"]) -(* t = { a = 42; b = "foo"; } *) -``` - -### `[@json.as "S"]`: customizing the representation of a variant case - -You can specify custom representation for a variant case using the `[@json.as -E]` attribute: - -```ocaml -type t = A | B [@json.as "bbb"] [@@deriving json] - -let json = to_json B -(* json = `String "bbb" *) -``` - -[ppx deriver plugin]: - https://ocaml.org/docs/metaprogramming#attributes-and-derivers -[melange]: https://melange.re