Last active
February 24, 2022 02:16
-
-
Save nektro/5b06c9050472e2a0bad73de4c8f9b563 to your computer and use it in GitHub Desktop.
A single line progress bar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
const string = []const u8; | |
const Progress = @This(); | |
const ansi = @import("ansi"); | |
const range = @import("range").range; | |
const extras = @import("extras"); | |
total: usize, | |
current: usize = 0, | |
last_print: i64 = 0, | |
width: u8 = 80, | |
prefix: string = "", | |
suffix: string = "", | |
// https://mike42.me/blog/2018-06-make-better-cli-progress-bars-with-unicode-block-characters | |
const bars = [_]string{ "", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█" }; | |
pub fn print(self: Progress) void { | |
const current = @intToFloat(f64, self.current); | |
const total = @intToFloat(f64, self.total); | |
const prog: f64 = current / total; | |
std.debug.print("{s}{} / {} ", .{ self.prefix, fmtByteCountIEC(self.current), fmtByteCountIEC(self.total) }); | |
const width: f64 = @intToFloat(f64, self.width) * 8; | |
std.debug.print("[", .{}); | |
const barprog = @floatToInt(usize, prog * width); | |
for (range(barprog / 8)) |_| std.debug.print("█", .{}); | |
std.debug.print("{s}", .{bars[barprog % 8]}); | |
for (range((@floatToInt(usize, width) - barprog) / 8)) |_| std.debug.print(" ", .{}); | |
std.debug.print("] ", .{}); | |
std.debug.print("{d:.3}%: {s}\n", .{ prog * 100, self.suffix }); | |
} | |
pub fn refresh(self: Progress) void { | |
std.debug.print(comptime ansi.csi.CursorUp(1), .{}); | |
std.debug.print(comptime ansi.csi.EraseInLine(0), .{}); | |
self.print(); | |
} | |
pub fn update(self: *Progress, amt: usize) void { | |
self.current += amt; | |
const now = std.time.milliTimestamp(); | |
if (now - self.last_print < 50) return; | |
self.last_print = now; | |
self.refresh(); | |
} | |
fn fmtByteCountIEC(b: usize) std.fmt.Formatter(formatByteCountIEC) { | |
return .{ .data = b }; | |
} | |
fn formatByteCountIEC(b: usize, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { | |
_ = fmt; | |
_ = options; | |
try reduceNumber(writer, b, 1024, "B", "KMGTPEZY"); | |
} | |
fn reduceNumber(writer: anytype, input: usize, comptime unit: usize, comptime base: string, comptime prefixes: string) !void { | |
if (input < unit) { | |
try writer.print("{d} {s}", .{ input, base }); | |
} | |
var div = unit; | |
var exp: usize = 0; | |
var n = input / unit; | |
while (n >= unit) : (n /= unit) { | |
div *= unit; | |
exp += 1; | |
} | |
try writer.print("{d:.3} {s}{s}", .{ @intToFloat(f64, input) / @intToFloat(f64, div), prefixes[exp..][0..1], base }); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
id: a2g2w2oc7r56kzq49kbqqp6u2v1bu5hgttjt00udpmiwwcse | |
name: Progress | |
main: Progress.zig | |
license: MIT | |
description: A single line progress bar | |
dependencies: | |
- src: git https://github.com/nektro/zig-ansi | |
- src: git https://github.com/nektro/zig-range | |
- src: git https://github.com/nektro/zig-extras |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment