package ppx_csv_conv
Generate functions to read/write records in csv format
Install
Dune Dependency
Authors
Maintainers
Sources
v0.17.0.tar.gz
sha256=069430f81559bfeca188da347f0e3aa7827bf69d8ac90e17d729c9d7e55fb4e5
doc/src/ppx_csv_conv_deprecated/ppx_csv_conv_deprecated.ml.html
Source file ppx_csv_conv_deprecated.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 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
open Base open Ppxlib open Ast_builder.Default let extension_name = "csv" let unsupported_type_error_msg ~name = Printf.sprintf "The type %s is not natively supported in the csv camlp4 extension" name ;; let useless_merge_recursive _log ~field_name:_ ~tp:_ ast = ast let edot ~loc path_opt id = pexp_ident ~loc (Located.mk ~loc (match path_opt with | None -> Longident.Lident id | Some p -> Longident.Ldot (p, id))) ;; (** Generate the list of fields contained in a flattened record type *) module Rev_headers = Ppx_conv_func.Of_simple (struct let unsupported_type_error_msg = unsupported_type_error_msg let conversion_name = extension_name let function_name = function | None -> "rev_csv_header'" | Some param -> Printf.sprintf "rev_csv_header_of_%s'" param ;; let atoms loc ~field_name = [%expr fun acc _ -> [%e estring ~loc field_name] :: acc] let merge_recursive = useless_merge_recursive let recursive loc ~field_name ~type_name:_ ~path = let tns = function_name None in let recursive = edot ~loc path tns in let is_csv_atom = edot ~loc path "is_csv_atom" in [%expr fun acc _ -> if [%e is_csv_atom] then [%e estring ~loc field_name] :: acc else [%e recursive] acc () ()] ;; end) (* Generate the specification of the headers as a tree. This is useful to generate headers consisting of multiple rows, each field grouping those below. *) module Spec_of_headers = Ppx_conv_func.Of_simple (struct let unsupported_type_error_msg = unsupported_type_error_msg let conversion_name = extension_name let function_name = function | None -> "rev_csv_header_spec'" | Some param -> Printf.sprintf "rev_csv_header_spec_of_%s'" param ;; let atoms loc ~field_name = [%expr fun acc _ -> Csvfields.Csv.Spec.Leaf [%e estring ~loc field_name] :: acc] ;; let merge_recursive = useless_merge_recursive let recursive loc ~field_name ~type_name:_ ~path = let tns = function_name None in let recursive = edot ~loc path tns in let is_csv_atom = edot ~loc path "is_csv_atom" in [%expr fun acc _ -> if [%e is_csv_atom] then Csvfields.Csv.Spec.Leaf [%e estring ~loc field_name] :: acc else Csvfields.Csv.Spec.Tree ([%e estring ~loc field_name], [%e recursive] [] () ()) :: acc] ;; end) (** Generate the some type using a csv row (a list of strings) *) module Type_of_csv_row = Ppx_conv_func.Of_complete (struct let unsupported_type_error_msg = unsupported_type_error_msg let conversion_name = extension_name let function_name = function | None -> failwith "Csv conversion of_row requires some name" | Some param -> Printf.sprintf "%s_of_row'" param ;; let unit loc ~field_name:_ = [%expr Csvfields.Csv.unit_of_row] let bool loc ~field_name:_ = [%expr Csvfields.Csv.bool_of_row] let string loc ~field_name:_ = [%expr Csvfields.Csv.string_of_row] let char loc ~field_name:_ = [%expr Csvfields.Csv.char_of_row] let int loc ~field_name:_ = [%expr Csvfields.Csv.int_of_row] let float loc ~field_name:_ = [%expr Csvfields.Csv.float_of_row] let int32 loc ~field_name:_ = [%expr Csvfields.Csv.int32_of_row] let int64 loc ~field_name:_ = [%expr Csvfields.Csv.int64_of_row] let nativeint loc ~field_name:_ = [%expr Csvfields.Csv.nativeint_of_row] let big_int loc ~field_name:_ = [%expr Csvfields.Csv.big_int_of_row] let nat loc ~field_name:_ = [%expr Csvfields.Csv.nat_of_row] let num loc ~field_name:_ = [%expr Csvfields.Csv.num_of_row] let ratio loc ~field_name:_ = [%expr Csvfields.Csv.ratio_of_row] let list loc ~field_name:_ = Ppx_conv_func.raise_unsupported ~loc "list" let array loc ~field_name:_ = Ppx_conv_func.raise_unsupported ~loc "list" let option loc ~field_name:_ = Ppx_conv_func.raise_unsupported ~loc "option" let lazy_t loc ~field_name:_ = Ppx_conv_func.raise_unsupported ~loc "lazy_t" let ref loc ~field_name:_ = Ppx_conv_func.raise_unsupported ~loc "ref" let merge_recursive = useless_merge_recursive let recursive loc ~field_name:_ ~type_name ~path = let tns = function_name (Some type_name) in edot ~loc path tns ;; end) module type B = sig val writer : Location.t -> arg_label * expression val is_first : Location.t -> arg_label * expression val is_last : Location.t -> arg_label * expression end module Make_row_of (S : B) = struct let unsupported_type_error_msg = unsupported_type_error_msg let conversion_name = extension_name let function_name = function | None -> failwith "Csv conversion write_row_of_ requires some name" | Some param -> Printf.sprintf "write_row_of_%s'" param ;; let add_arguments expr loc = pexp_apply ~loc expr [ S.is_first loc; S.is_last loc; S.writer loc ] ;; let unit loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_unit] loc let bool loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_bool] loc let string loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_string] loc let char loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_char] loc let int loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_int] loc let float loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_float] loc let int32 loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_int32] loc let int64 loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_int64] loc let nativeint loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_nativeint] loc ;; let big_int loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_big_int] loc let nat loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_nat] loc let num loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_num] loc let ratio loc ~field_name:_ = add_arguments [%expr Csvfields.Csv.row_of_ratio] loc let merge_recursive = useless_merge_recursive let recursive loc ~field_name:_ ~type_name ~path = let tns = function_name (Some type_name) in add_arguments (edot ~loc path tns) loc ;; let list loc ~field_name:_ = Ppx_conv_func.raise_unsupported ~loc "list" let array loc ~field_name:_ = Ppx_conv_func.raise_unsupported ~loc "array" let option loc ~field_name:_ = Ppx_conv_func.raise_unsupported ~loc "option" let lazy_t loc ~field_name:_ = Ppx_conv_func.raise_unsupported ~loc "lazy_t" let ref loc ~field_name:_ = Ppx_conv_func.raise_unsupported ~loc "ref" end let falseexpr loc = [%expr false] module Unique_row_of = Ppx_conv_func.Of_complete (Make_row_of (struct let writer loc = Labelled "writer", [%expr writer] let is_first loc = Labelled "is_first", [%expr is_first] let is_last loc = Labelled "is_last", [%expr is_last] end)) module First_row_of = Ppx_conv_func.Of_complete (Make_row_of (struct let writer loc = Labelled "writer", [%expr writer] let is_first loc = Labelled "is_first", [%expr is_first] let is_last loc = Labelled "is_last", falseexpr loc end)) module Middle_row_of = Ppx_conv_func.Of_complete (Make_row_of (struct let writer loc = Labelled "writer", [%expr writer] let is_first loc = Labelled "is_first", falseexpr loc let is_last loc = Labelled "is_last", falseexpr loc end)) module Last_row_of = Ppx_conv_func.Of_complete (Make_row_of (struct let writer loc = Labelled "writer", [%expr writer] let is_first loc = Labelled "is_first", falseexpr loc let is_last loc = Labelled "is_last", [%expr is_last] end)) let csv_record_sig loc ~record_name = let st = psig_include ~loc (include_infos ~loc (pmty_with ~loc (pmty_ident ~loc (Located.lident ~loc "Csvfields.Csv.Csvable")) [ Pwith_typesubst ( Located.lident ~loc "t" , type_declaration ~loc ~name:(Located.mk ~loc "t") ~params:[] ~manifest: (Some (ptyp_constr ~loc (Located.lident ~loc record_name) [])) ~cstrs:[] ~kind:Ptype_abstract ~private_:Public ) ])) in [ st ] ;; let rev_csv_header' ~record_name ~lds loc = let name = [%pat? rev_csv_header'] in let conversion_of_type = Rev_headers.conversion_of_type in Ppx_conv_func.Gen_struct.generate_using_fold ~record_name ~pass_acc:true ~pass_anonymous:true ~conversion_of_type ~name ~lds loc ;; let rev_csv_header_spec' ~record_name ~lds loc = let name = [%pat? rev_csv_header_spec'] in let conversion_of_type = Spec_of_headers.conversion_of_type in Ppx_conv_func.Gen_struct.generate_using_fold ~record_name ~pass_acc:true ~pass_anonymous:true ~conversion_of_type ~name ~lds loc ;; let fields_module ~record_name ~loc ~suffix = Ast_helper.Exp.ident { loc ; txt = Longident.parse (Printf.sprintf "%s.%s" (match String.equal record_name "t" with | true -> "Fields" | false -> Printf.sprintf "Fields_of_%s" record_name) suffix) } ;; let row_of_t' ~record_name ~lds loc = let init = [%expr [%e fields_module ~record_name ~loc ~suffix:"Direct.iter"] t] in let body = Ppx_conv_func.Gen_struct.make_body ~lds ~init loc ~unique_f:Unique_row_of.conversion_of_type ~first_f:First_row_of.conversion_of_type ~last_f:Last_row_of.conversion_of_type Middle_row_of.conversion_of_type in let anonymous = Ppx_conv_func.Gen_struct.anonymous loc in let func = [%expr fun ~is_first ~is_last ~writer [%p anonymous] [%p anonymous] t -> [%e body]] in [%stri let write_row_of_t' = [%e func]] ;; let t_of_row' ~record_name ~lds loc = let init = [%expr [%e fields_module ~record_name ~loc ~suffix:"make_creator"] strings] in let body = let f = Type_of_csv_row.conversion_of_type in Ppx_conv_func.Gen_struct.make_body ~lds ~init loc f in let func = Ppx_conv_func.lambda loc [ Ppx_conv_func.Gen_struct.anonymous loc; [%pat? strings] ] body in [%stri let t_of_row' = [%e func]] ;; let csv_record ~tps:_ ~record_name loc lds = let t_of_row' = t_of_row' ~record_name ~lds loc in let is_csv_atom = [%stri let is_csv_atom = false] in let row_of_t' = row_of_t' ~record_name ~lds loc in let rev_csv_header' = rev_csv_header' ~record_name ~lds loc in let rev_csv_header_spec' = rev_csv_header_spec' ~record_name ~lds loc in let t = if String.( <> ) record_name "t" then [%str type t = [%t ptyp_constr ~loc (Located.lident ~loc record_name) []]] else [%str type _t = t type t = _t] in let with_constraints = [ Pwith_typesubst ( Located.lident ~loc "t" , type_declaration ~loc ~name:(Located.mk ~loc "t") ~manifest:(Some (ptyp_constr ~loc (Located.lident ~loc record_name) [])) ~kind:Ptype_abstract ~private_:Public ~params:[] ~cstrs:[] ) ] in let applied_functor = pmod_apply ~loc (pmod_ident ~loc (Located.lident ~loc "Csvfields.Csv.Record")) (pmod_structure ~loc (t @ [ is_csv_atom; rev_csv_header'; rev_csv_header_spec'; t_of_row'; row_of_t' ])) in let st = pstr_include ~loc (include_infos ~loc (pmod_constraint ~loc applied_functor (pmty_with ~loc (pmty_ident ~loc (Located.lident ~loc "Csvfields.Csv.Csvable")) with_constraints))) in [ st ; [%stri let [%p pvar ~loc (record_name ^ "_of_row")] = t_of_row] ; [%stri let [%p pvar ~loc ("row_of_" ^ record_name)] = row_of_t] ; [%stri let [%p pvar ~loc (record_name ^ "_of_row'")] = t_of_row'] ; [%stri let [%p pvar ~loc ("write_row_of_" ^ record_name ^ "'")] = write_row_of_t'] ] ;; let csv = let str_type_decl = Deriving.Generator.make Deriving.Args.empty (Ppx_conv_func.Gen_struct.generate ~extension_name ~record:csv_record) ~deps:[ Ppx_fields_conv.fields ] in let sig_type_decl = Deriving.Generator.make Deriving.Args.empty (Ppx_conv_func.Gen_sig.generate ~extension_name ~nil:(fun ~tps:_ ~record_name loc -> csv_record_sig loc ~record_name) ~record:(fun ~tps:_ ~record_name loc _ -> csv_record_sig loc ~record_name)) in Deriving.add extension_name ~str_type_decl ~sig_type_decl ;;
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>