Source file column_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
open! Core
open! Import

module Align = struct
  type t =
    | Left
    | Right
    | Center
  [@@deriving sexp_of]
end

module Show = struct
  type t =
    [ `Yes
    | `No
    | `If_not_empty
    ]
  [@@deriving sexp_of]
end

module type Column = sig @@ portable
  module Align = Align
  module Show = Show

  type 'a t [@@deriving sexp_of]

  (** creates a column given the header and the to-string function.

      NOTE: the boundary between columns [x] and [y] is drawn iff
      [x.right_boundary || y.left_boundary]. For columns on the edge, [left_boundary] and
      [right_boundary] dictate whether the edge of the table is drawn. *)
  val create
    :  ?align:Align.t (* Default: left *)
    -> ?min_width:int
    -> ?max_width:int
    -> ?show:[ `Yes | `No | `If_not_empty ] (* Default: `Yes *)
    -> ?left_boundary:bool (* Default: true *)
    -> ?right_boundary:bool (* Default: true *)
    -> string
    -> ('a -> string)
    -> 'a t

  (** like create, except that the to_string function must provide a list of attributes. *)
  val create_attr
    :  ?align:Align.t (* Default: left *)
    -> ?min_width:int
    -> ?max_width:int
    -> ?show:[ `Yes | `No | `If_not_empty ] (* Default: `Yes *)
    -> ?left_boundary:bool (* Default: true *)
    -> ?right_boundary:bool (* Default: true *)
    -> string
    -> ('a -> Attr.t list * string)
    -> 'a t

  (** like create_attr, except that you can specify many lines with different attributes. *)
  val create_attrs
    :  ?align:Align.t (* Default: left *)
    -> ?min_width:int
    -> ?max_width:int
    -> ?show:[ `Yes | `No | `If_not_empty ] (* Default: `Yes *)
    -> ?left_boundary:bool (* Default: true *)
    -> ?right_boundary:bool (* Default: true *)
    -> string
    -> ('a -> (Attr.t list * string) list)
    -> 'a t

  val lift : 'a t -> f:('b -> 'a) -> 'b t
  val optional : 'a t -> 'a option t
  val align : _ t -> Align.t
  val header : 'a t -> string
  val show : _ t -> Show.t
  val to_data : 'a t -> 'a -> (Attr.t list * string) list
  val update_header : f:(string -> string) -> 'a t -> 'a t
  val update_show : f:(Show.t -> Show.t) -> 'a t -> 'a t

  module Of_field : sig
    (** This module is used for constructing lists of ['a t]s from a record's fields. The
        intention is to use [Fields.to_list] to obtain a list. *)

    (** Create a column based on a field of a record. *)
    val field
      :  ?align:Align.t (* Default: left *)
      -> ?min_width:int
      -> ?max_width:int
      -> ?show:[ `Yes | `No | `If_not_empty ]
      -> ?left_boundary:bool
      -> ?right_boundary:bool
      -> ?header:string (** Defaults to field name *)
      -> ('field -> string)
      -> ('record, 'field) Field.t
      -> 'record t

    (** [field_attr] is to [field] as [create_attr] is to [create]. *)
    val field_attr
      :  ?align:Align.t (* Default: left *)
      -> ?min_width:int
      -> ?max_width:int
      -> ?show:[ `Yes | `No | `If_not_empty ]
      -> ?left_boundary:bool
      -> ?right_boundary:bool
      -> ?header:string (** Defaults to field name *)
      -> ('field -> Attr.t list * string)
      -> ('record, 'field) Field.t
      -> 'record t

    (** Like [field], but defaults to [""] if [None] *)
    val field_opt
      :  ?align:Align.t (* Default: left *)
      -> ?min_width:int
      -> ?max_width:int
      -> ?show:[ `Yes | `No | `If_not_empty ]
      -> ?left_boundary:bool
      -> ?right_boundary:bool
      -> ?header:string (** Defaults to field name *)
      -> ('field -> string)
      -> ('record, 'field option) Field.t
      -> 'record t

    (** Like [field_attr], but defaults to [([], "")] if [None] *)
    val field_opt_attr
      :  ?align:Align.t (* Default: left *)
      -> ?min_width:int
      -> ?max_width:int
      -> ?show:[ `Yes | `No | `If_not_empty ]
      -> ?left_boundary:bool
      -> ?right_boundary:bool
      -> ?header:string (** Defaults to field name *)
      -> ('field -> Attr.t list * string)
      -> ('record, 'field option) Field.t
      -> 'record t
  end

  module Private : sig
    (** [layout ts values ~spacing ~max_width = widths] where the nth int in [widths] is
        the width to which the nth column in [ts] should wrap its contents.

        [spacing] is the number of spaces to leave on either side of the contents of each
        cell. [layout] also leaves a character per column for a vertical separator.
        [layout] raises if all this cannot fit into [max_width]. *)
    val layout : 'a t list -> 'a list -> spacing:int -> max_width:int -> int list

    val to_cell : 'a t -> value:'a -> Cell.t
    val left_boundary : _ t -> bool
    val right_boundary : _ t -> bool
  end
end