package ppx_jsobject_conv
Ppx plugin for Typeconv to derive conversion from ocaml types to js objects to use with js_of_ocaml
Install
Dune Dependency
Authors
Maintainers
Sources
v0.10.0.tar.gz
sha256=bfdfeb470157e285ab5e70ee281f87ccd7efe9997c8b77e6c81aa498d19a670e
md5=a3c6fb4e0a8e3a1268c12bdf94f0b763
doc/src/ppx_jsobject_conv.runtime/ppx_jsobject_conv_runtime.ml.html
Source file ppx_jsobject_conv_runtime.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 226 227 228 229 230 231 232 233 234 235 236
open StdLabels type jsfunction = Js_of_ocaml.Js.Unsafe.any Js_of_ocaml.Js.t let map f e = match e with | Ok x -> Ok (f x) | Error s -> Error s let flat_map f e = match e with | Ok x -> f x | Error s -> Error s let map_err f e = match e with | Ok _ as res -> res | Error y -> Error (f y) let (>|=) e f = map f e let (>>=) e f = flat_map f e let (>*=) e f = map_err f e let result_of_bool v er = if v then Ok(v) else Error(er) let throw_js_error msg = let err = Js_of_ocaml.Js.Unsafe.new_obj Js_of_ocaml.Js.error_constr [|Js_of_ocaml.Js.Unsafe.inject @@ Js_of_ocaml.Js.string msg|] in Js_of_ocaml.Js_error.raise_ err let string_typeof v = let tpof = Js_of_ocaml.Js.typeof v in if tpof = (Js_of_ocaml.Js.string "object") then ( if Js_of_ocaml.Js.instanceof v Js_of_ocaml.Js.array_empty then "array" else (if Js_of_ocaml.Js.instanceof v (Js_of_ocaml.Js.Unsafe.get Js_of_ocaml.Js.Unsafe.global (Js_of_ocaml.Js.string "String")) then "string" else (if Js_of_ocaml.Js.Opt.test @@ Js_of_ocaml.Js.some v then "object" else "null"))) else Js_of_ocaml.Js.to_string tpof let type_error v expected = Error("expected " ^ expected ^ ", got " ^(string_typeof v)) let concat_error_messages path msg = if String.contains msg ':' then path ^ "." ^ msg else path ^ ": " ^ msg (* of_jsobject *) (* heplers *) exception Short_circuit of string let array_fold_right_short_circuit ~f arr ~init = try Ok(snd @@ Array.fold_right ~f:(fun el (i, acc) -> match f i el acc with | Ok(v) -> (i + 1, v) | Error(s) -> raise @@ Short_circuit(s)) ~init:(0, init) arr) with Short_circuit(s) -> Error(s) let is_object v = let msg = "expected object, got " ^ (string_typeof v) in result_of_bool (string_typeof v = "object") msg >|= (fun _ -> v) let is_array v = let msg = "expected array, got " ^ (string_typeof v) in result_of_bool (Js_of_ocaml.Js.instanceof v Js_of_ocaml.Js.array_empty) msg >|= (fun _ -> let arr:'a Js_of_ocaml.Js.t #Js_of_ocaml.Js.js_array Js_of_ocaml.Js.t = Js_of_ocaml.Js.Unsafe.coerce v in arr) let array_length_f (arr : 'a Js_of_ocaml.Js.t #Js_of_ocaml.Js.js_array Js_of_ocaml.Js.t) : int = (Js_of_ocaml.Js.Unsafe.get arr (Js_of_ocaml.Js.string "length")) let is_array_of_size_n obj expected = is_array obj >>= fun arr -> let got = array_length_f arr in result_of_bool (expected = got) ("expected array of length " ^ string_of_int expected ^ ", got " ^ string_of_int got) >|= fun _ -> arr let array_get_ind arr ind = match Js_of_ocaml.Js.Optdef.to_option @@ Js_of_ocaml.Js.array_get arr ind with | Some v -> Ok(v) | None -> Ok(Js_of_ocaml.Js.Unsafe.eval_string("undefined")) let object_get_key (obj: 'a Js_of_ocaml.Js.t) (key:string) = Ok(Js_of_ocaml.Js.Unsafe.get obj (Js_of_ocaml.Js.string key)) let defined_or_error obj = match Js_of_ocaml.Js.Optdef.to_option @@ Js_of_ocaml.Js.def obj with | Some(o) -> Ok(o) | None -> Error("expected value, got undefined") let defined_or_default a__of_jsobject dflt obj = match Js_of_ocaml.Js.Opt.to_option @@ Js_of_ocaml.Js.some obj with | Some(v) -> a__of_jsobject v | None -> Ok(dflt) let convert_or_default a__of__jsobject default obj = match a__of__jsobject obj with | Error _ -> Ok default | Ok _ as ok -> ok (* conversion *) let bool_of_jsobject obj = if string_typeof obj = "boolean" then Ok(Js_of_ocaml.Js.to_bool @@ Js_of_ocaml.Js.Unsafe.coerce obj) else type_error obj "boolean" let unit_of_jsobject obj = if string_typeof obj = "undefined" then Ok(()) else type_error obj "undefined" let int_of_jsobject obj = if string_typeof obj = "number" then Ok(int_of_float @@ (* TODO: check for "int-nesses" *) Js_of_ocaml.Js.float_of_number @@ Js_of_ocaml.Js.Unsafe.coerce obj) else type_error obj "number" let float_of_jsobject obj = if string_typeof obj = "number" then Ok(Js_of_ocaml.Js.float_of_number @@ Js_of_ocaml.Js.Unsafe.coerce obj) else type_error obj "number" let string_of_jsobject obj = (* XXX: should we have an option for such liberal conversion? *) if (string_typeof obj = "string") then Ok(Js_of_ocaml.Js.to_string (Js_of_ocaml.Js.Unsafe.coerce obj)) else (if (string_typeof obj = "number") then Ok(string_of_int @@ int_of_float @@ Js_of_ocaml.Js.float_of_number @@ Js_of_ocaml.Js.Unsafe.coerce obj) else type_error obj "string") let option_of_jsobject a__of_jsobject obj = match Js_of_ocaml.Js.Opt.to_option @@ Js_of_ocaml.Js.some obj with | Some(v) -> (match Js_of_ocaml.Js.Opt.to_option @@ Js_of_ocaml.Js.some v with | Some(v') ->a__of_jsobject v' >|= (fun i -> Some(i)) | None -> Ok(None) ) | None -> Ok(None) let list_of_jsobject a__of_jsobject obj = is_array obj >>= (fun arr -> let oarr = Js_of_ocaml.Js.to_array arr in array_fold_right_short_circuit ~f:(fun i jsel l -> a__of_jsobject jsel >*= (fun emsg -> concat_error_messages (string_of_int i) emsg) >|= (fun oel -> oel::l)) ~init:[] oarr) let object_get_sole_key (obj: 'a Js_of_ocaml.Js.t) = let keys = Js_of_ocaml.Js.object_keys obj in is_array_of_size_n keys 1 >*= (fun e -> "Object keys -- " ^ e) >>= (fun ar -> array_get_ind ar 0) >>= string_of_jsobject let array_of_jsobject a__of_jsobject obj = list_of_jsobject a__of_jsobject obj >|= Array.of_list let jsfunction_of_jsobject obj = if string_typeof obj = "function" then Ok(Obj.magic obj) else type_error obj "function" let jst_of_jsobject obj = Ok(Obj.magic obj) let jsany_of_jsobject obj = Ok(Obj.magic obj) (* jsobject_of *) (* helpers *) let inject o = Js_of_ocaml.Js.Unsafe.inject o let new_array l = Js_of_ocaml.Js.Unsafe.new_obj Js_of_ocaml.Js.array_length [| inject l |] let to_js_array l = let arr = new_array @@ List.length l in let set = Js_of_ocaml.Js.array_set arr in let () = List.iteri ~f:set l in arr let make_jsobject pairs = Js_of_ocaml.Js.Unsafe.obj @@ Array.map pairs ~f:(fun (k, v)-> (k, inject v)) let make_jsobject_of_some pairs = let unwrap_some l = Array.of_list @@ List.rev @@ Array.fold_left l ~init:[] ~f:(fun acc i -> match i with | None -> acc | Some c -> (c::acc)) in make_jsobject @@ unwrap_some pairs let number_of_int i = Js_of_ocaml.Js.number_of_float @@ float_of_int i (* conversions *) let jsobject_of_bool v = Js_of_ocaml.Js.Unsafe.coerce @@ Js_of_ocaml.Js.bool v let jsobject_of_unit () = Obj.magic Js_of_ocaml.Js.undefined let jsobject_of_int v = Js_of_ocaml.Js.Unsafe.coerce @@ number_of_int v let jsobject_of_string v = Js_of_ocaml.Js.Unsafe.coerce @@ Js_of_ocaml.Js.string v let jsobject_of_float v = Js_of_ocaml.Js.Unsafe.coerce @@ Js_of_ocaml.Js.number_of_float v let jsobject_of_option jsobject_of__a = function | Some(x) -> jsobject_of__a x | None -> Obj.magic Js_of_ocaml.Js.null let jsobject_of_list jsobject_of__a lst = to_js_array @@ List.rev @@ List.rev_map ~f:jsobject_of__a lst let jsobject_of_array jsobject_of__a arr = to_js_array @@ Array.to_list @@ Array.map ~f:jsobject_of__a arr let jsobject_of_jsfunction v = Obj.magic v let jsobject_of_jst v = Js_of_ocaml.Js.Unsafe.coerce v let jsobject_of_jsany v = v
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>