diff options
| author | 2026-06-08 06:24:06 +0000 | |
|---|---|---|
| committer | 2026-06-08 06:24:06 +0000 | |
| commit | e4cf4b6152bf05387828dda44bd73d7ec12a7ed6 (patch) | |
| tree | 157e92eaabd9c910f9a83b53dc9c26754dcce12d /internal/progress/render.go | |
| parent | common/iowrap: Remove in favor of lgo (diff) | |
| signature | No signature | |
internal/progress: Add
Diffstat (limited to 'internal/progress/render.go')
| -rw-r--r-- | internal/progress/render.go | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/internal/progress/render.go b/internal/progress/render.go new file mode 100644 index 00000000..f51852eb --- /dev/null +++ b/internal/progress/render.go @@ -0,0 +1,79 @@ +package progress + +import ( + "fmt" + "strings" + "time" + + "lindenii.org/go/furgit/internal/utils" + "lindenii.org/go/lgo/fmt/humanize" + "lindenii.org/go/lgo/intconv" +) + +func (meter *Meter) render(now time.Time, eol string) { + if meter.delay > 0 && now.Sub(meter.startedAt) < meter.delay && eol == "\r" { + return + } + + meter.refreshThroughput(now) + + counters := meter.renderCounters() + + clear1 := 0 + if len(counters) < meter.lastCounterW { + clear1 = meter.lastCounterW - len(counters) + 1 + } + + meter.lastCounterW = len(counters) + + line := meter.title + ": " + counters + if clear1 > 0 { + line += strings.Repeat(" ", clear1) + } + + line += eol + + utils.BestEffortFprintf(meter.writer, "%s", line) + + if meter.writer != nil { + _ = meter.writer.Flush() + } +} + +func (meter *Meter) renderCounters() string { + if meter.total > 0 { + u, err := intconv.Uint64ToInt(meter.lastDone * 100 / meter.total) + if err != nil { + return "overflow" + // TODO + } + + meter.lastPercent = u + + return fmt.Sprintf("%3d%% (%d/%d)%s", meter.lastPercent, meter.lastDone, meter.total, meter.throughputSuffix) + } + + return fmt.Sprintf("%d%s", meter.lastDone, meter.throughputSuffix) +} + +func (meter *Meter) refreshThroughput(now time.Time) { + if !meter.throughput { + return + } + + if meter.nextThroughput.After(now) && meter.throughputSuffix != "" { + return + } + + for !now.Before(meter.nextThroughput) { + meter.nextThroughput = meter.nextThroughput.Add(throughputInterval) + } + + elapsed := now.Sub(meter.startedAt) + if elapsed <= 0 { + return + } + + rate := uint64(float64(meter.lastBytes) / elapsed.Seconds()) + meter.throughputSuffix = ", " + humanize.Bytes(meter.lastBytes) + " | " + humanize.Bytes(rate) + "/s" +} |
