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[<AutoOpen>]
module Duets.Cli.Components.ProgressBar
open FSharp.Data.UnitSystems.SI.UnitNames
open Spectre.Console
let private sleepForProgressBar (stepDuration: int<second>) =
async { do! Async.Sleep(stepDuration * 1000 / 4 |> int) }
|> Async.RunSynchronously
/// <summary>
/// Renders a progress bar that shows each of the given step names one at a time
/// waiting for the specified `stepDuration` between each step.
/// </summary>
/// <param name="stepNames">Text of the steps to show</param>
/// <param name="stepDuration">Duration of each of the steps</param>
let showProgressBarSync stepNames (stepDuration: int<second>) =
AnsiConsole
.Progress()
.Start(fun ctx ->
stepNames
|> List.iter (fun stepName ->
let task = ctx.AddTask(stepName)
for _ in 0..4 do
task.Increment 25.0
sleepForProgressBar stepDuration))
/// <summary>
/// Renders a progress bar that shows each of the given step names all at the
/// same time, increasing the steps randomly and waiting for the specified
/// `stepDuration` between each step.
/// </summary>
/// <param name="stepNames">Text of the steps to show</param>
/// <param name="stepDuration">Duration of each of the steps</param>
let showProgressBarAsync stepNames (stepDuration: int<second>) =
AnsiConsole
.Progress()
.Start(fun ctx ->
let tasks =
stepNames
|> List.map (fun name -> ctx.AddTask(name))
|> ResizeArray
let random = System.Random()
for _ in 0 .. 4 * tasks.Count - 1 do
let randomIndex = random.Next(0, tasks.Count)
let taskToIncrement = tasks.[randomIndex]
taskToIncrement.Increment 25.0
if taskToIncrement.IsFinished then
tasks.RemoveAt(randomIndex)
sleepForProgressBar stepDuration)