package core_extended

  1. Overview
  2. Docs
Extra components that are not as closely vetted or as stable as Core

Install

Dune Dependency

Authors

Maintainers

Sources

core_extended-v0.14.0.tar.gz
sha256=a7bf672f617891b10e405f1edb1c2ddc1db9e5b3169bd278bbb75b84d57d23ce
md5=00eb9b3ed6b0b02f74a2cf01e4d5827f

doc/src/core_extended.delimited_kernel/read_intf.ml.html

Source file read_intf.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
open Core_kernel

(** If we can read a row correctly but the ['a t] provided can't convert it,
    your ['a On_invalid_row.t] will define what happens.

    Here, 'read a row correctly' means that it's valid CSV (subject to your
    delimiter etc) & it has the correct number of columns. If that's not the
    case the parsers will just raise. *)
module type On_invalid_row = sig
  type 'a t

  (** The default. Raise. *)
  val raise : _ t

  (** Skip the bad row *)
  val skip : _ t

  (** Do something else!

      - [`Skip]: skip the line. Same as [skip] above.
      - [`Yield]: return the given value for this row.
      - [`Raise]: raise the given exception
  *)
  val create
    :  (int String.Map.t (** Map from header to position. *)
        -> string Append_only_buffer.t (** Value at each position. *)
        -> exn (** Exception raised when trying to convert this row. *)
        -> [ `Skip | `Yield of 'a | `Raise of exn ])
    -> 'a t
end

module type Open_on_rhs = sig
  type 'a t

  val at_index : int -> f:(string -> 'a) -> 'a t
  val at_header : string -> f:(string -> 'a) -> 'a t
  val at_header_opt : string -> f:(string option -> 'a) -> 'a t
end

module type Root = sig
  (** Row up to the error, and the field with the error up to the point of
      failure. Same as [Expert.Parse_state.Bad_csv_formatting]. *)
  exception Bad_csv_formatting of string list * string

  (** This provides an applicative interface for constructing values from a csv file.

      An ['a t] describes how to build an OCaml model ['a] for each row.

      Simple example:
      {[
        type t =
          { foo : int
          ; bar : string
          }

        (* Describes how to generate a [t] from a row of a csv file *)
        let parse : t Delimited_kernel.Parse.t =
          let open Delimited_kernel.Parse.Let_syntax in
          let%map_open foo = at_header "foo" ~f:Int.of_string
          and bar = at_header "bar" ~f:String.of_string in
          { foo; bar }
        ;;

        let _ =
          Delimited_kernel.Parse.list_of_string ~header:`Yes parse
            "foo,bar\n2,\"hello, world\"\n"
        ;;
      ]}
  *)
  type 'a t

  include Applicative.S with type 'a t := 'a t

  module Open_on_rhs_intf : sig
    module type S = Open_on_rhs with type 'a t := 'a t
  end

  include
    Applicative.Let_syntax
    with type 'a t := 'a t
    with module Open_on_rhs_intf := Open_on_rhs_intf

  (** Read a field at the given index. Use [f] to convert the field from string. *)
  val at_index : int -> f:(string -> 'a) -> 'a t

  (** Read a field at the given header. Use [f] to convert the field from string.

      Note that if the given header is not provided through either the file or
      the [~header] argument to the parsers, this will fail at runtime.  *)
  val at_header : string -> f:(string -> 'a) -> 'a t

  (** Read a field at the given header, if it exists. Use [f] to convert the field from
      string. *)
  val at_header_opt : string -> f:(string option -> 'a) -> 'a t

  module On_invalid_row : On_invalid_row

  (** Header parsing control *)
  module Header = Header

  (** Whole-row parsing. *)
  module Row : sig
    type 'a builder_t = 'a t

    include module type of Row

    (** A builder for [Row.t]s.

        As this parses the whole row it's slower than using the builder
        interface directly, but simpler to use. *)
    val builder : t builder_t
  end


  (** Fold the CSV rows contained in the given string. *)
  val fold_string
    :  ?strip:bool
    -> ?sep:char
    -> ?quote:[ `No_quoting | `Using of char ]
    -> ?header:Header.t
    -> ?on_invalid_row:'a On_invalid_row.t
    -> 'a t
    -> init:'b
    -> f:('b -> 'a -> 'b)
    -> string
    -> 'b

  (** Load the CSV as a list *)
  val list_of_string
    :  ?strip:bool
    -> ?sep:char
    -> ?quote:[ `No_quoting | `Using of char ]
    -> ?header:Header.t
    -> ?on_invalid_row:'a On_invalid_row.t
    -> 'a t
    -> string
    -> 'a list

  (** Read CSV file. *)
  val read_lines
    :  ?strip:bool
    -> ?sep:char
    -> ?quote:[ `No_quoting | `Using of char ]
    -> ?header:Header.t
    -> ?on_invalid_row:'a On_invalid_row.t
    -> 'a t
    -> In_channel.t
    -> 'a list
end

module type Expert = sig
  module Append_only_buffer = Append_only_buffer
  module Parse_state = Parse_state
  module On_invalid_row : On_invalid_row

  type 'a t

  val create_parse_state
    :  ?strip:bool
    -> ?sep:char
    -> ?quote:[ `No_quoting | `Using of char ]
    -> ?on_invalid_row:'a On_invalid_row.t
    -> header_map:int String.Map.t
    -> 'a t
    -> init:'b
    -> f:('b -> 'a -> 'b)
    -> 'b Parse_state.t

  module Builder : sig
    type nonrec 'a t = 'a t

    val lambda : (int String.Map.t -> string Append_only_buffer.t -> 'a) -> 'a t
    val return : 'a -> 'a t
  end

  module Parse_header : sig
    (** Type [t] represents an incomplete header parse. Keep calling [input] on it until you
        get a map from header name to column number. *)
    type t

    val create
      :  ?strip:bool
      -> ?sep:char
      -> ?quote:[ `No_quoting | `Using of char ]
      -> ?header:Header.t
      -> unit
      -> (t, int String.Map.t) Either.t

    (** [input t ~len s] reads the first [len] bytes from [s] and returns either [t] or
        [header_map, unused_input]. *)
    val input : t -> len:int -> Bytes.t -> (t, int String.Map.t * string) Either.t

    val input_string : t -> len:int -> string -> (t, int String.Map.t * string) Either.t
  end

  (** This creates a function that can be fed partial input to return partial parses.
      Please do not use this in new code. *)
  val create_partial
    :  ?strip:bool
    -> ?sep:char
    -> ?quote:[ `No_quoting | `Using of char ]
    -> ?header:Header.t
    -> unit
    -> ([ `Data of string | `Eof ] -> Row.t list) Staged.t
end
OCaml

Innovation. Community. Security.