aboutsummaryrefslogtreecommitdiffstats
path: root/ydb/public/lib/ydb_cli/common/progress_bar.cpp
blob: c2643418a26e3415acbe6c7e89cb01c75a619d2a (plain) (blame)
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
#include "common.h"
#include "progress_bar.h"

#include <ydb/public/lib/ydb_cli/common/interactive.h>
#include <util/string/cast.h>

namespace NYdb {
namespace NConsoleClient {

TProgressBar::TProgressBar(size_t capacity) : Capacity(capacity) {
}

void TProgressBar::SetProcess(size_t progress)
{
    CurProgress = Min(progress, Capacity);
    Render();
}

void TProgressBar::AddProgress(size_t value) {
    CurProgress = Min(CurProgress + value, Capacity);
    if (Capacity == 0) {
        return;
    }
    Render();
}

TProgressBar::~TProgressBar() {
    if (!Finished) {
        Cout << Endl;
    }
}

void TProgressBar::Render()
{
    std::optional<size_t> barLenOpt = GetTerminalWidth();
    if (!barLenOpt)
        return;

    size_t barLen = *barLenOpt;
    TString output = "\r";
    output += ToString(CurProgress * 100 / Capacity);
    output += "% |";
    TString outputEnd = "| [";
    outputEnd += ToString(CurProgress);
    outputEnd += "/";
    outputEnd += ToString(Capacity);
    outputEnd += "]";

    if (barLen > output.Size() - 1) {
        barLen -= output.Size() - 1;
    } else {
        barLen = 1;
    }

    if (barLen > outputEnd.Size()) {
        barLen -= outputEnd.Size();
    } else {
        barLen = 1;
    }

    size_t filledBarLen = CurProgress * barLen / Capacity;
    output += TString("█") * filledBarLen;
    output += TString("░") * (barLen - filledBarLen);
    output += outputEnd;
    Cout << output;
    if (CurProgress == Capacity) {
        Cout << "\n";
        Finished = true;
    }
    Cout.Flush();
}

} // namespace NConsoleClient
} // namespace NYdb