package melange-json-native
Compositional JSON encode/decode PPX for OCaml
Install
Dune Dependency
Authors
Maintainers
Sources
melange-json-1.3.0.tbz
sha256=9ed376e19793c536f8a8a388f0e1ce7e402d1fde85de4e941ab5bd1190b25ac5
sha512=3b66695707a6a7cf9fed59fef9ddb02504a4e85d14dd904764ea049c4e92d0910e1d68b4edfe2b8a1d2e1c984bd061d01d3866dd575bfd7c0573ff5a4865c616
doc/src/ppx_deriving_json_native/ppx_deriving_json_native.ml.html
Source file ppx_deriving_json_native.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
open Printf open StdLabels open Ppxlib open Ast_builder.Default open Ppx_deriving_tools open Ppx_deriving_tools.Conv open Ppx_deriving_json_common module Of_json = struct let with_refs ~loc prefix fs inner = let gen_name n = sprintf "%s_%s" prefix n in let gen_expr (n : label loc) = pexp_ident ~loc:n.loc { loc = n.loc; txt = lident (gen_name n.txt) } in List.fold_left (List.rev fs) ~init:(inner gen_expr) ~f:(fun next ld -> let n = ld.pld_name in let patt = ppat_var ~loc:n.loc { loc = n.loc; txt = gen_name n.txt } in [%expr let [%p patt] = ref [%e match ld_attr_default ld with | Some default -> [%expr Stdlib.Option.Some [%e default]] | None -> [%expr Stdlib.Option.None]] in [%e next]]) let build_tuple ~loc derive es ts = let args = List.fold_left (List.rev (List.combine es ts)) ~init:[] ~f:(fun prev (x, t) -> let this = derive t x in this :: prev) in pexp_tuple ~loc args let build_record ~allow_extra_fields ~loc derive fs x make = with_refs ~loc "x" fs @@ fun ename -> let handle_field k v = let fail_case = [%pat? name] --> if allow_extra_fields then [%expr ()] else [%expr Ppx_deriving_json_runtime.of_json_error (Stdlib.Printf.sprintf "unknown field: %s" name)] in let cases = List.fold_left (List.rev fs) ~init:[ fail_case ] ~f:(fun next ld -> let key = Option.value ~default:ld.pld_name (ld_attr_json_key ld) in pstring ~loc:key.loc key.txt --> [%expr [%e ename ld.pld_name] := Stdlib.Option.Some [%e derive ld.pld_type v]] :: next) in pexp_match ~loc k cases in let build = let fields = List.map fs ~f:(fun ld -> let key = Option.value ~default:ld.pld_name (ld_attr_json_key ld) in let default = ld_attr_default ld in ( map_loc lident ld.pld_name, [%expr match Stdlib.( ! ) [%e ename ld.pld_name] with | Stdlib.Option.Some v -> v | Stdlib.Option.None -> [%e match default with | Some default -> default | None -> [%expr Ppx_deriving_json_runtime.of_json_error [%e estring ~loc:key.loc (sprintf "missing field %S" key.txt)]]]] )) in pexp_record ~loc fields None in [%expr let rec iter = function | [] -> () | (n', v) :: fs -> [%e handle_field [%expr n'] [%expr v]]; iter fs in iter [%e x]; [%e make build]] let derive_of_tuple derive t x = let loc = t.tpl_loc in let n = List.length t.tpl_types in let xpatt, xexprs = gen_pat_list ~loc "x" n in let xpatt = [%pat? `List [%p xpatt]] in pexp_match ~loc x [ xpatt --> build_tuple ~loc derive xexprs t.tpl_types; [%pat? _] --> [%expr Ppx_deriving_json_runtime.of_json_error [%e estring ~loc (sprintf "expected a JSON array of length %i" n)]]; ] let derive_of_record derive t x = let loc = t.rcd_loc in let allow_extra_fields = Option.is_some (td_attr_json_allow_extra_fields t.rcd_ctx) in pexp_match ~loc x [ [%pat? `Assoc fs] --> build_record ~allow_extra_fields ~loc derive t.rcd_fields [%expr fs] Fun.id; [%pat? _] --> [%expr Ppx_deriving_json_runtime.of_json_error [%e estring ~loc (sprintf "expected a JSON object")]]; ] let derive_of_variant_case derive make vcs = match vcs with | Vcs_enum (n, ctx) -> let loc = n.loc in let n = Option.value ~default:n (vcs_attr_json_as ctx) in [%pat? `String [%p pstring ~loc:n.loc n.txt]] --> make None | Vcs_tuple (n, t) -> let loc = n.loc in let n = Option.value ~default:n (vcs_attr_json_as t.tpl_ctx) in let arity = List.length t.tpl_types in if arity = 0 then [%pat? `List [ `String [%p pstring ~loc:n.loc n.txt] ]] --> make None else let xpatt, xexprs = gen_pat_list ~loc "x" arity in [%pat? `List (`String [%p pstring ~loc:n.loc n.txt] :: [%p xpatt])] --> make (Some (build_tuple ~loc derive xexprs t.tpl_types)) | Vcs_record (n, t) -> let loc = n.loc in let n = Option.value ~default:n (vcs_attr_json_as t.rcd_ctx) in let allow_extra_fields = match t.rcd_ctx with | Vcs_ctx_variant cd -> Option.is_some (cd_attr_json_allow_extra_fields cd) | Vcs_ctx_polyvariant _ -> false in [%pat? `List [ `String [%p pstring ~loc:n.loc n.txt]; `Assoc fs ]] --> build_record ~allow_extra_fields ~loc derive t.rcd_fields [%expr fs] (fun e -> make (Some e)) let deriving : Ppx_deriving_tools.deriving = deriving_of_match () ~name:"of_json" ~of_t:(fun ~loc -> [%type: Yojson.Basic.t]) ~error:(fun ~loc -> [%expr Ppx_deriving_json_runtime.of_json_error "invalid JSON"]) ~derive_of_tuple ~derive_of_record ~derive_of_variant_case end module To_json = struct let derive_of_tuple derive t es = let loc = t.tpl_loc in let es = List.map2 t.tpl_types es ~f:derive in [%expr `List [%e elist ~loc es]] let derive_of_record derive t es = let loc = t.rcd_loc in let es = List.map2 t.rcd_fields es ~f:(fun ld x -> let key = Option.value ~default:ld.pld_name (ld_attr_json_key ld) in [%expr [%e estring ~loc:key.loc key.txt], [%e derive ld.pld_type x]]) in [%expr `Assoc [%e elist ~loc es]] let derive_of_variant_case derive vcs es = match vcs with | Vcs_enum (n, ctx) -> let loc = n.loc in let n = Option.value ~default:n (vcs_attr_json_as ctx) in [%expr `String [%e estring ~loc:n.loc n.txt]] | Vcs_tuple (n, t) -> let loc = n.loc in let n = Option.value ~default:n (vcs_attr_json_as t.tpl_ctx) in [%expr `List (`String [%e estring ~loc:n.loc n.txt] :: [%e elist ~loc (List.map2 t.tpl_types es ~f:derive)])] | Vcs_record (n, t) -> let loc = n.loc in let n = Option.value ~default:n (vcs_attr_json_as t.rcd_ctx) in [%expr `List (`String [%e estring ~loc:n.loc n.txt] :: [ [%e derive_of_record derive t es] ])] let deriving : Ppx_deriving_tools.deriving = deriving_to () ~name:"to_json" ~t_to:(fun ~loc -> [%type: Yojson.Basic.t]) ~derive_of_tuple ~derive_of_record ~derive_of_variant_case end let () = let _ = Ppx_deriving_tools.register Of_json.deriving in let _ = Ppx_deriving_tools.register To_json.deriving in let _ = Ppx_deriving_tools.( register_combined "json" [ To_json.deriving; Of_json.deriving ]) in ()
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>