package progress

  1. Overview
  2. Docs

Module Make.LineSource

Sourcetype 'a t

The type of progress lines for reported values of type 'a. This module provides a selection of individual line segments that can be combined to produce more interesting layouts. You may wish to look over the examples for inspiration.

Basic line segments

Sourceval const : string -> _ t

const s is the segment that always displays s.

Sourceval constf : ('a, Format.formatter, unit, _ t) format4 -> 'a

Like const, but takes a format string and corresponding arguments. constf "..." a b c ... is equivalent to const (Format.asprintf "..." a b c ...), except that colours added with Fmt.styled are not discarded.

Sourceval string : string t

A line segment that displays a dynamically-sized string message. Use lpad and rpad to pad the message up to a given length.

Sourceval lpad : int -> 'a t -> 'a t

lpad n t left-pads the segment t to size n by adding blank space at the start.

Sourceval rpad : int -> 'a t -> 'a t

rpad n t right-pads the segment t to size n by adding blank space at the end.

Sourceval of_printer : ?init:'a -> 'a Printer.t -> 'a t

of_printer p is a segment that renders the latest reported value using printer p. See sum for a variant that reports accumulated values instead.

Counting segments

These segments all consume integer values and display the accumulated total of reported values in some way. The top-level Line segments are specialised to int values; see "Alternative integer types" for variants supporting int32, int64 etc.

Sourceval count_to : ?pp:int Printer.t -> ?sep:unit t -> int -> int t

count_to target renders both the current running total of reported values and the fixed value target, separated by the the given separator, i.e. 42/100. sep defaults to const "/".

Sourceval bytes : int t

Prints the running total as a number of bytes, using ISO/IEC binary prefixes (e.g. 10.4 MiB). See also bytes_per_sec.

Sourceval percentage_of : int -> int t

percentage_of target renders the running total as a percentage of target, i.e. 42%. Values outside the range [0, 100] will be clamped to either 0 or 100.

Sourceval sum : ?pp:int Printer.t -> width:int -> unit -> int t

sum ~width () displays a running total of reported values using width-many terminal columns. If passed, pp overrides the printer used for rendering the count.

Graphical segments

Sourcemodule Bar_style : sig ... end
Sourceval bar : ?style:[ `ASCII | `UTF8 | `Custom of Bar_style.t ] -> ?color:Color.t -> ?width:[ `Fixed of int | `Expand ] -> ?data:[ `Sum | `Latest ] -> int -> int t

bar total is a progress bar of the form: [#################...............]

The proportion of the bar that is filled is given by <reported_so_far> / total. Optional parameters are as follows:

  • ?style specifies whether to use a UTF-8 or an ASCII encoding for the progress bar. The UTF-8 encoding shows a higher resolution of progress, but may not be supported in all terminals. The default is `ASCII.
  • ?color causes the filled portion of the bar to be rendered with the given colour. (Equivalent to setting the colour with Bar_style.with_color.)
  • ?width is the width of the bar in columns. Defaults to `Expand, which causes the bar to occupy the remaining rendering space after accounting for other line segments on the same line.
  • ?data changes the metric that is indicated by the progress bar. `Sum (the default) causes the progress bar to correspond to the running total of values reported so far. `Latest causes each reported value to overwrite the previous one instead.
Sourceval spinner : ?frames:string list -> ?color:Color.t -> ?min_interval:Duration.t option -> unit -> _ t

spinner () is a small segment that cycles over a fixed number of frames each time a value is reported. e.g.

  ⠋ → ⠙ → ⠹ → ⠸ → ⠼ → ⠴ → ⠦ → ⠧ → ⠇ → ⠏ → ...

Optional prameters are as follows:

  • ?frames alters the sequence of frames rendered by the spinner;
  • ?color causes each frame to be rendered with the given colour;
  • ?min_interval is the minimum time interval between frame transitions of the spinner (i.e. a debounce threshold). The default is Some 80ms.

Time-sensitive segments

Sourceval bytes_per_sec : int t

bytes_per_sec renders the rate of change of the running total as a number of bytes per second, using ISO/IEC binary prefixes (e.g. 10.4 MiB/s).

Sourceval elapsed : ?pp:Duration.t Printer.t -> unit -> _ t

Displays the time for which the bar has been rendering in MM:SS form.

Sourceval eta : ?pp:Duration.t Printer.t -> int -> int t

Displays an estimate of the remaining time until total is accumulated by the reporters, in MM:SS form.

Sourceval rate : float Printer.t -> int t

rate pp is an integer segment that uses pp to print the rate of reported values per second. (For instance, bytes_per_sec is rate Units.Bytes.of_float.)

Combining segments

Sourceval (++) : 'a t -> 'a t -> 'a t

Horizontally join two segments of the same reported value type.

Sourceval list : ?sep:'a t -> 'a t list -> 'a t

Horizontally join a list of segments, with a given separator. sep defaults to const " ".

Sourceval pair : ?sep:unit t -> 'a t -> 'b t -> ('a * 'b) t

Horizontally join a pair of segments consuming different reported values into a single segment that consumes a pair.

Sourceval using : ('a -> 'b) -> 'b t -> 'a t

using f s is a segment that first applies f to the reported value and then behaves as segment s.

Utilities

The following line segments are definable in terms of the others, but provided for convenience:

Sourceval parens : 'a t -> 'a t

parens t is const "(" ++ t ++ const ")".

Sourceval brackets : 'a t -> 'a t

brackets t is const "[" ++ t ++ const "]".

Sourceval braces : 'a t -> 'a t

braces t is const "{" ++ t ++ const "}".

Sourceval noop : unit -> _ t

A zero-width line segment that does nothing. This segment will not be surrounded with separators when used in a list, making it a useful "off" state for conditionally-enabled segments.

Sourceval spacer : int -> _ t

spacer n is const (String.make n ' ').

Sourceval ticker_to : ?sep:unit t -> int -> _ t

ticker_to total is using ~f:(fun _ -> 1) (counter_to total). i.e. it renders the total number of reported values of some arbitrary type.

Alternative integer types

Many of the line segments above are specialised to int values for simplicity (and performance), but certain use-cases may require different types (e.g. for file transfers greater than 2 GiB on 32-bit platforms). The following modules re-export the Line DSL with different integer specialisations, and are intended to be opened locally, e.g.

  let my_line =
    let open Progress.Line.Using_int64 in
    list [ const "Downloading large file"; bar total; bytes ]
Sourcemodule Integer_dependent : sig ... end
Sourcemodule Using_int32 : Integer_dependent.Ext with type integer := int32
Sourcemodule Using_int64 : Integer_dependent.Ext with type integer := int64
Sourcemodule Using_float : Integer_dependent.Ext with type integer := float

Examples

  (* Renders: "[######---------------------------------------]  14/100" *)
  bar 100 ++ const " " ++ count_to 100
  (* Renders: "⠏ [01:04] [####-----------------]  293.9 MiB (eta: 07:12)" *)
  list
    [ spinner ()
    ; brackets (elapsed ())
    ; bar total
    ; bytes
    ; parens (const "eta: " ++ eta total)
    ]
  (* Renders: "  a.txt │██████████████████████████▋   │   91.4 MiB/s  92%" *)
  list
    [ lpad 7 (const file_name)
    ; bar ~style:`UTF8 total
    ; bytes_per_sec
    ; percentage_of total
    ]

See the examples/ directory of the source repository for more.

Library internals

Sourcemodule Internals : sig ... end

Exposes the underlying implementation of line segments for testing. This API is unstable, unsafe and mostly undocumented; here be dragons etc.

OCaml

Innovation. Community. Security.