Commit 916b645fc1

daurnimator <quae@daurnimator.com>
2021-04-10 13:09:38
Have std.fmt functions take case as an enum
1 parent b82d642
lib/std/math/big/int.zig
@@ -1140,20 +1140,20 @@ pub const Const = struct {
         out_stream: anytype,
     ) !void {
         comptime var radix = 10;
-        comptime var uppercase = false;
+        comptime var case: std.fmt.Case = .lower;
 
         if (fmt.len == 0 or comptime mem.eql(u8, fmt, "d")) {
             radix = 10;
-            uppercase = false;
+            case = .lower;
         } else if (comptime mem.eql(u8, fmt, "b")) {
             radix = 2;
-            uppercase = false;
+            case = .lower;
         } else if (comptime mem.eql(u8, fmt, "x")) {
             radix = 16;
-            uppercase = false;
+            case = .lower;
         } else if (comptime mem.eql(u8, fmt, "X")) {
             radix = 16;
-            uppercase = true;
+            case = .upper;
         } else {
             @compileError("Unknown format string: '" ++ fmt ++ "'");
         }
@@ -1171,7 +1171,7 @@ pub const Const = struct {
             .positive = false,
         };
         var buf: [biggest.sizeInBaseUpperBound(radix)]u8 = undefined;
-        const len = self.toString(&buf, radix, uppercase, &limbs);
+        const len = self.toString(&buf, radix, case, &limbs);
         return out_stream.writeAll(buf[0..len]);
     }
 
@@ -1179,7 +1179,7 @@ pub const Const = struct {
     /// Caller owns returned memory.
     /// Asserts that `base` is in the range [2, 16].
     /// See also `toString`, a lower level function than this.
-    pub fn toStringAlloc(self: Const, allocator: *Allocator, base: u8, uppercase: bool) Allocator.Error![]u8 {
+    pub fn toStringAlloc(self: Const, allocator: *Allocator, base: u8, case: std.fmt.Case) Allocator.Error![]u8 {
         assert(base >= 2);
         assert(base <= 16);
 
@@ -1192,7 +1192,7 @@ pub const Const = struct {
         const limbs = try allocator.alloc(Limb, calcToStringLimbsBufferLen(self.limbs.len, base));
         defer allocator.free(limbs);
 
-        return allocator.shrink(string, self.toString(string, base, uppercase, limbs));
+        return allocator.shrink(string, self.toString(string, base, case, limbs));
     }
 
     /// Converts self to a string in the requested base.
@@ -1204,7 +1204,7 @@ pub const Const = struct {
     /// length of at least `calcToStringLimbsBufferLen`.
     /// In the case of power-of-two base, `limbs_buffer` is ignored.
     /// See also `toStringAlloc`, a higher level function than this.
-    pub fn toString(self: Const, string: []u8, base: u8, uppercase: bool, limbs_buffer: []Limb) usize {
+    pub fn toString(self: Const, string: []u8, base: u8, case: std.fmt.Case, limbs_buffer: []Limb) usize {
         assert(base >= 2);
         assert(base <= 16);
 
@@ -1223,7 +1223,7 @@ pub const Const = struct {
                 var shift: usize = 0;
                 while (shift < limb_bits) : (shift += base_shift) {
                     const r = @intCast(u8, (limb >> @intCast(Log2Limb, shift)) & @as(Limb, base - 1));
-                    const ch = std.fmt.digitToChar(r, uppercase);
+                    const ch = std.fmt.digitToChar(r, case);
                     string[digits_len] = ch;
                     digits_len += 1;
                     // If we hit the end, it must be all zeroes from here.
@@ -1269,7 +1269,7 @@ pub const Const = struct {
                 var r_word = r.limbs[0];
                 var i: usize = 0;
                 while (i < digits_per_limb) : (i += 1) {
-                    const ch = std.fmt.digitToChar(@intCast(u8, r_word % base), uppercase);
+                    const ch = std.fmt.digitToChar(@intCast(u8, r_word % base), case);
                     r_word /= base;
                     string[digits_len] = ch;
                     digits_len += 1;
@@ -1281,7 +1281,7 @@ pub const Const = struct {
 
                 var r_word = q.limbs[0];
                 while (r_word != 0) {
-                    const ch = std.fmt.digitToChar(@intCast(u8, r_word % base), uppercase);
+                    const ch = std.fmt.digitToChar(@intCast(u8, r_word % base), case);
                     r_word /= base;
                     string[digits_len] = ch;
                     digits_len += 1;
@@ -1615,9 +1615,9 @@ pub const Managed = struct {
 
     /// Converts self to a string in the requested base. Memory is allocated from the provided
     /// allocator and not the one present in self.
-    pub fn toString(self: Managed, allocator: *Allocator, base: u8, uppercase: bool) ![]u8 {
+    pub fn toString(self: Managed, allocator: *Allocator, base: u8, case: std.fmt.Case) ![]u8 {
         if (base < 2 or base > 16) return error.InvalidBase;
-        return self.toConst().toStringAlloc(self.allocator, base, uppercase);
+        return self.toConst().toStringAlloc(self.allocator, base, case);
     }
 
     /// To allow `std.fmt.format` to work with `Managed`.
lib/std/math/big/int_test.zig
@@ -277,7 +277,7 @@ test "big.int string to" {
     var a = try Managed.initSet(testing.allocator, 120317241209124781241290847124);
     defer a.deinit();
 
-    const as = try a.toString(testing.allocator, 10, false);
+    const as = try a.toString(testing.allocator, 10, .lower);
     defer testing.allocator.free(as);
     const es = "120317241209124781241290847124";
 
@@ -288,14 +288,14 @@ test "big.int string to base base error" {
     var a = try Managed.initSet(testing.allocator, 0xffffffff);
     defer a.deinit();
 
-    try testing.expectError(error.InvalidBase, a.toString(testing.allocator, 45, false));
+    try testing.expectError(error.InvalidBase, a.toString(testing.allocator, 45, .lower));
 }
 
 test "big.int string to base 2" {
     var a = try Managed.initSet(testing.allocator, -0b1011);
     defer a.deinit();
 
-    const as = try a.toString(testing.allocator, 2, false);
+    const as = try a.toString(testing.allocator, 2, .lower);
     defer testing.allocator.free(as);
     const es = "-1011";
 
@@ -306,7 +306,7 @@ test "big.int string to base 16" {
     var a = try Managed.initSet(testing.allocator, 0xefffffff00000001eeeeeeefaaaaaaab);
     defer a.deinit();
 
-    const as = try a.toString(testing.allocator, 16, false);
+    const as = try a.toString(testing.allocator, 16, .lower);
     defer testing.allocator.free(as);
     const es = "efffffff00000001eeeeeeefaaaaaaab";
 
@@ -317,7 +317,7 @@ test "big.int neg string to" {
     var a = try Managed.initSet(testing.allocator, -123907434);
     defer a.deinit();
 
-    const as = try a.toString(testing.allocator, 10, false);
+    const as = try a.toString(testing.allocator, 10, .lower);
     defer testing.allocator.free(as);
     const es = "-123907434";
 
@@ -328,7 +328,7 @@ test "big.int zero string to" {
     var a = try Managed.initSet(testing.allocator, 0);
     defer a.deinit();
 
-    const as = try a.toString(testing.allocator, 10, false);
+    const as = try a.toString(testing.allocator, 10, .lower);
     defer testing.allocator.free(as);
     const es = "0";
 
@@ -1180,7 +1180,7 @@ test "big.int div multi-multi zero-limb trailing (with rem)" {
 
     try testing.expect((try q.to(u128)) == 0x10000000000000000);
 
-    const rs = try r.toString(testing.allocator, 16, false);
+    const rs = try r.toString(testing.allocator, 16, .lower);
     defer testing.allocator.free(rs);
     try testing.expect(std.mem.eql(u8, rs, "4444444344444443111111111111111100000000000000000000000000000000"));
 }
@@ -1199,7 +1199,7 @@ test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-li
 
     try testing.expect((try q.to(u128)) == 0x1);
 
-    const rs = try r.toString(testing.allocator, 16, false);
+    const rs = try r.toString(testing.allocator, 16, .lower);
     defer testing.allocator.free(rs);
     try testing.expect(std.mem.eql(u8, rs, "444444434444444311111111111111110000000000000000"));
 }
@@ -1216,11 +1216,11 @@ test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-li
     defer r.deinit();
     try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
 
-    const qs = try q.toString(testing.allocator, 16, false);
+    const qs = try q.toString(testing.allocator, 16, .lower);
     defer testing.allocator.free(qs);
     try testing.expect(std.mem.eql(u8, qs, "10000000000000000820820803105186f"));
 
-    const rs = try r.toString(testing.allocator, 16, false);
+    const rs = try r.toString(testing.allocator, 16, .lower);
     defer testing.allocator.free(rs);
     try testing.expect(std.mem.eql(u8, rs, "4e11f2baa5896a321d463b543d0104e30000000000000000"));
 }
@@ -1240,11 +1240,11 @@ test "big.int div multi-multi fuzz case #1" {
     defer r.deinit();
     try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
 
-    const qs = try q.toString(testing.allocator, 16, false);
+    const qs = try q.toString(testing.allocator, 16, .lower);
     defer testing.allocator.free(qs);
     try testing.expect(std.mem.eql(u8, qs, "3ffffffffffffffffffffffffffff0000000000000000000000000000000000001ffffffffffffffffffffffffffff7fffffffe000000000000000000000000000180000000000000000000003fffffbfffffffdfffffffffffffeffff800000100101000000100000000020003fffffdfbfffffe3ffffffffffffeffff7fffc00800a100000017ffe000002000400007efbfff7fe9f00000037ffff3fff7fffa004006100000009ffe00000190038200bf7d2ff7fefe80400060000f7d7f8fbf9401fe38e0403ffc0bdffffa51102c300d7be5ef9df4e5060007b0127ad3fa69f97d0f820b6605ff617ddf7f32ad7a05c0d03f2e7bc78a6000e087a8bbcdc59e07a5a079128a7861f553ddebed7e8e56701756f9ead39b48cd1b0831889ea6ec1fddf643d0565b075ff07e6caea4e2854ec9227fd635ed60a2f5eef2893052ffd54718fa08604acbf6a15e78a467c4a3c53c0278af06c4416573f925491b195e8fd79302cb1aaf7caf4ecfc9aec1254cc969786363ac729f914c6ddcc26738d6b0facd54eba026580aba2eb6482a088b0d224a8852420b91ec1"));
 
-    const rs = try r.toString(testing.allocator, 16, false);
+    const rs = try r.toString(testing.allocator, 16, .lower);
     defer testing.allocator.free(rs);
     try testing.expect(std.mem.eql(u8, rs, "310d1d4c414426b4836c2635bad1df3a424e50cbdd167ffccb4dfff57d36b4aae0d6ca0910698220171a0f3373c1060a046c2812f0027e321f72979daa5e7973214170d49e885de0c0ecc167837d44502430674a82522e5df6a0759548052420b91ec1"));
 }
@@ -1264,11 +1264,11 @@ test "big.int div multi-multi fuzz case #2" {
     defer r.deinit();
     try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
 
-    const qs = try q.toString(testing.allocator, 16, false);
+    const qs = try q.toString(testing.allocator, 16, .lower);
     defer testing.allocator.free(qs);
     try testing.expect(std.mem.eql(u8, qs, "40100400fe3f8fe3f8fe3f8fe3f8fe3f8fe4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f91e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4992649926499264991e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4792e4b92e4b92e4b92e4b92a4a92a4a92a4"));
 
-    const rs = try r.toString(testing.allocator, 16, false);
+    const rs = try r.toString(testing.allocator, 16, .lower);
     defer testing.allocator.free(rs);
     try testing.expect(std.mem.eql(u8, rs, "a900000000000000000000000000000000000000000000000000"));
 }
@@ -1533,7 +1533,7 @@ test "big.int pow" {
 
         try testing.expect(a.eq(y));
 
-        const ys = try y.toString(testing.allocator, 16, false);
+        const ys = try y.toString(testing.allocator, 16, .lower);
         defer testing.allocator.free(ys);
         try testing.expectEqualSlices(
             u8,
lib/std/zig/fmt.zig
@@ -68,7 +68,7 @@ pub fn formatEscapes(
         // Use hex escapes for rest any unprintable characters.
         else => {
             try writer.writeAll("\\x");
-            try std.fmt.formatInt(byte, 16, false, .{ .width = 2, .fill = '0' }, writer);
+            try std.fmt.formatInt(byte, 16, .lower, .{ .width = 2, .fill = '0' }, writer);
         },
     };
 }
lib/std/fmt.zig
@@ -370,15 +370,15 @@ pub fn formatAddress(value: anytype, options: FormatOptions, writer: anytype) @T
         .Pointer => |info| {
             try writer.writeAll(@typeName(info.child) ++ "@");
             if (info.size == .Slice)
-                try formatInt(@ptrToInt(value.ptr), 16, false, FormatOptions{}, writer)
+                try formatInt(@ptrToInt(value.ptr), 16, .lower, FormatOptions{}, writer)
             else
-                try formatInt(@ptrToInt(value), 16, false, FormatOptions{}, writer);
+                try formatInt(@ptrToInt(value), 16, .lower, FormatOptions{}, writer);
             return;
         },
         .Optional => |info| {
             if (@typeInfo(info.child) == .Pointer) {
                 try writer.writeAll(@typeName(info.child) ++ "@");
-                try formatInt(@ptrToInt(value), 16, false, FormatOptions{}, writer);
+                try formatInt(@ptrToInt(value), 16, .lower, FormatOptions{}, writer);
                 return;
             }
         },
@@ -651,7 +651,7 @@ pub fn formatIntValue(
     writer: anytype,
 ) !void {
     comptime var radix = 10;
-    comptime var uppercase = false;
+    comptime var case: Case = .lower;
 
     const int_value = if (@TypeOf(value) == comptime_int) blk: {
         const Int = math.IntFittingRange(value, value);
@@ -660,7 +660,7 @@ pub fn formatIntValue(
 
     if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "d")) {
         radix = 10;
-        uppercase = false;
+        case = .lower;
     } else if (comptime std.mem.eql(u8, fmt, "c")) {
         if (@typeInfo(@TypeOf(int_value)).Int.bits <= 8) {
             return formatAsciiChar(@as(u8, int_value), options, writer);
@@ -675,21 +675,21 @@ pub fn formatIntValue(
         }
     } else if (comptime std.mem.eql(u8, fmt, "b")) {
         radix = 2;
-        uppercase = false;
+        case = .lower;
     } else if (comptime std.mem.eql(u8, fmt, "x")) {
         radix = 16;
-        uppercase = false;
+        case = .lower;
     } else if (comptime std.mem.eql(u8, fmt, "X")) {
         radix = 16;
-        uppercase = true;
+        case = .upper;
     } else if (comptime std.mem.eql(u8, fmt, "o")) {
         radix = 8;
-        uppercase = false;
+        case = .lower;
     } else {
         @compileError("Unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
     }
 
-    return formatInt(int_value, radix, uppercase, options, writer);
+    return formatInt(int_value, radix, case, options, writer);
 }
 
 fn formatFloatValue(
@@ -724,8 +724,10 @@ fn formatFloatValue(
     return formatBuf(buf_stream.getWritten(), options, writer);
 }
 
-fn formatSliceHexImpl(comptime uppercase: bool) type {
-    const charset = "0123456789" ++ if (uppercase) "ABCDEF" else "abcdef";
+pub const Case = enum { lower, upper };
+
+fn formatSliceHexImpl(comptime case: Case) type {
+    const charset = "0123456789" ++ if (case == .upper) "ABCDEF" else "abcdef";
 
     return struct {
         pub fn f(
@@ -745,8 +747,8 @@ fn formatSliceHexImpl(comptime uppercase: bool) type {
     };
 }
 
-const formatSliceHexLower = formatSliceHexImpl(false).f;
-const formatSliceHexUpper = formatSliceHexImpl(true).f;
+const formatSliceHexLower = formatSliceHexImpl(.lower).f;
+const formatSliceHexUpper = formatSliceHexImpl(.upper).f;
 
 /// Return a Formatter for a []const u8 where every byte is formatted as a pair
 /// of lowercase hexadecimal digits.
@@ -754,14 +756,14 @@ pub fn fmtSliceHexLower(bytes: []const u8) std.fmt.Formatter(formatSliceHexLower
     return .{ .data = bytes };
 }
 
-/// Return a Formatter for a []const u8 where every byte is formatted as a pair
+/// Return a Formatter for a []const u8 where every byte is formatted as pair
 /// of uppercase hexadecimal digits.
 pub fn fmtSliceHexUpper(bytes: []const u8) std.fmt.Formatter(formatSliceHexUpper) {
     return .{ .data = bytes };
 }
 
-fn formatSliceEscapeImpl(comptime uppercase: bool) type {
-    const charset = "0123456789" ++ if (uppercase) "ABCDEF" else "abcdef";
+fn formatSliceEscapeImpl(comptime case: Case) type {
+    const charset = "0123456789" ++ if (case == .upper) "ABCDEF" else "abcdef";
 
     return struct {
         pub fn f(
@@ -788,8 +790,8 @@ fn formatSliceEscapeImpl(comptime uppercase: bool) type {
     };
 }
 
-const formatSliceEscapeLower = formatSliceEscapeImpl(false).f;
-const formatSliceEscapeUpper = formatSliceEscapeImpl(true).f;
+const formatSliceEscapeLower = formatSliceEscapeImpl(.lower).f;
+const formatSliceEscapeUpper = formatSliceEscapeImpl(.upper).f;
 
 /// Return a Formatter for a []const u8 where every non-printable ASCII
 /// character is escaped as \xNN, where NN is the character in lowercase
@@ -1034,13 +1036,13 @@ pub fn formatFloatScientific(
         if (exp > -10 and exp < 10) {
             try writer.writeAll("0");
         }
-        try formatInt(exp, 10, false, FormatOptions{ .width = 0 }, writer);
+        try formatInt(exp, 10, .lower, FormatOptions{ .width = 0 }, writer);
     } else {
         try writer.writeAll("-");
         if (exp > -10 and exp < 10) {
             try writer.writeAll("0");
         }
-        try formatInt(-exp, 10, false, FormatOptions{ .width = 0 }, writer);
+        try formatInt(-exp, 10, .lower, FormatOptions{ .width = 0 }, writer);
     }
 }
 
@@ -1133,7 +1135,7 @@ pub fn formatFloatHexadecimal(
 
     // +1 for the decimal part.
     var buf: [1 + mantissa_digits]u8 = undefined;
-    const N = formatIntBuf(&buf, mantissa, 16, false, .{ .fill = '0', .width = 1 + mantissa_digits });
+    const N = formatIntBuf(&buf, mantissa, 16, .lower, .{ .fill = '0', .width = 1 + mantissa_digits });
 
     try writer.writeAll("0x");
     try writer.writeByte(buf[0]);
@@ -1150,7 +1152,7 @@ pub fn formatFloatHexadecimal(
             try writer.writeByteNTimes('0', precision - trimmed.len);
     };
     try writer.writeAll("p");
-    try formatInt(exponent - exponent_bias, 10, false, .{}, writer);
+    try formatInt(exponent - exponent_bias, 10, .lower, .{}, writer);
 }
 
 /// Print a float of the format x.yyyyy where the number of y is specified by the precision argument.
@@ -1299,7 +1301,7 @@ pub fn formatFloatDecimal(
 pub fn formatInt(
     value: anytype,
     base: u8,
-    uppercase: bool,
+    case: Case,
     options: FormatOptions,
     writer: anytype,
 ) !void {
@@ -1326,7 +1328,7 @@ pub fn formatInt(
     while (true) {
         const digit = a % base;
         index -= 1;
-        buf[index] = digitToChar(@intCast(u8, digit), uppercase);
+        buf[index] = digitToChar(@intCast(u8, digit), case);
         a /= base;
         if (a == 0) break;
     }
@@ -1348,9 +1350,9 @@ pub fn formatInt(
     return formatBuf(buf[index..], options, writer);
 }
 
-pub fn formatIntBuf(out_buf: []u8, value: anytype, base: u8, uppercase: bool, options: FormatOptions) usize {
+pub fn formatIntBuf(out_buf: []u8, value: anytype, base: u8, case: Case, options: FormatOptions) usize {
     var fbs = std.io.fixedBufferStream(out_buf);
-    formatInt(value, base, uppercase, options, fbs.writer()) catch unreachable;
+    formatInt(value, base, case, options, fbs.writer()) catch unreachable;
     return fbs.pos;
 }
 
@@ -1365,7 +1367,7 @@ fn formatDuration(ns: u64, comptime fmt: []const u8, options: std.fmt.FormatOpti
     }) |unit| {
         if (ns_remaining >= unit.ns) {
             const units = ns_remaining / unit.ns;
-            try formatInt(units, 10, false, .{}, writer);
+            try formatInt(units, 10, .lower, .{}, writer);
             try writer.writeByte(unit.sep);
             ns_remaining -= units * unit.ns;
             if (ns_remaining == 0) return;
@@ -1379,12 +1381,12 @@ fn formatDuration(ns: u64, comptime fmt: []const u8, options: std.fmt.FormatOpti
     }) |unit| {
         const kunits = ns_remaining * 1000 / unit.ns;
         if (kunits >= 1000) {
-            try formatInt(kunits / 1000, 10, false, .{}, writer);
+            try formatInt(kunits / 1000, 10, .lower, .{}, writer);
             const frac = kunits % 1000;
             if (frac > 0) {
                 // Write up to 3 decimal places
                 var buf = [_]u8{ '.', 0, 0, 0 };
-                _ = formatIntBuf(buf[1..], frac, 10, false, .{ .fill = '0', .width = 3 });
+                _ = formatIntBuf(buf[1..], frac, 10, .lower, .{ .fill = '0', .width = 3 });
                 var end: usize = 4;
                 while (end > 1) : (end -= 1) {
                     if (buf[end - 1] != '0') break;
@@ -1396,7 +1398,7 @@ fn formatDuration(ns: u64, comptime fmt: []const u8, options: std.fmt.FormatOpti
         }
     }
 
-    try formatInt(ns_remaining, 10, false, .{}, writer);
+    try formatInt(ns_remaining, 10, .lower, .{}, writer);
     try writer.writeAll("ns");
     return;
 }
@@ -1673,10 +1675,10 @@ pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {
     return value;
 }
 
-pub fn digitToChar(digit: u8, uppercase: bool) u8 {
+pub fn digitToChar(digit: u8, case: Case) u8 {
     return switch (digit) {
         0...9 => digit + '0',
-        10...35 => digit + ((if (uppercase) @as(u8, 'A') else @as(u8, 'a')) - 10),
+        10...35 => digit + ((if (case == .upper) @as(u8, 'A') else @as(u8, 'a')) - 10),
         else => unreachable,
     };
 }
@@ -1728,25 +1730,25 @@ test "bufPrintInt" {
     var buffer: [100]u8 = undefined;
     const buf = buffer[0..];
 
-    try std.testing.expectEqualSlices(u8, "-1", bufPrintIntToSlice(buf, @as(i1, -1), 10, false, FormatOptions{}));
+    try std.testing.expectEqualSlices(u8, "-1", bufPrintIntToSlice(buf, @as(i1, -1), 10, .lower, FormatOptions{}));
 
-    try std.testing.expectEqualSlices(u8, "-101111000110000101001110", bufPrintIntToSlice(buf, @as(i32, -12345678), 2, false, FormatOptions{}));
-    try std.testing.expectEqualSlices(u8, "-12345678", bufPrintIntToSlice(buf, @as(i32, -12345678), 10, false, FormatOptions{}));
-    try std.testing.expectEqualSlices(u8, "-bc614e", bufPrintIntToSlice(buf, @as(i32, -12345678), 16, false, FormatOptions{}));
-    try std.testing.expectEqualSlices(u8, "-BC614E", bufPrintIntToSlice(buf, @as(i32, -12345678), 16, true, FormatOptions{}));
+    try std.testing.expectEqualSlices(u8, "-101111000110000101001110", bufPrintIntToSlice(buf, @as(i32, -12345678), 2, .lower, FormatOptions{}));
+    try std.testing.expectEqualSlices(u8, "-12345678", bufPrintIntToSlice(buf, @as(i32, -12345678), 10, .lower, FormatOptions{}));
+    try std.testing.expectEqualSlices(u8, "-bc614e", bufPrintIntToSlice(buf, @as(i32, -12345678), 16, .lower, FormatOptions{}));
+    try std.testing.expectEqualSlices(u8, "-BC614E", bufPrintIntToSlice(buf, @as(i32, -12345678), 16, .upper, FormatOptions{}));
 
-    try std.testing.expectEqualSlices(u8, "12345678", bufPrintIntToSlice(buf, @as(u32, 12345678), 10, true, FormatOptions{}));
+    try std.testing.expectEqualSlices(u8, "12345678", bufPrintIntToSlice(buf, @as(u32, 12345678), 10, .upper, FormatOptions{}));
 
-    try std.testing.expectEqualSlices(u8, "   666", bufPrintIntToSlice(buf, @as(u32, 666), 10, false, FormatOptions{ .width = 6 }));
-    try std.testing.expectEqualSlices(u8, "  1234", bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 6 }));
-    try std.testing.expectEqualSlices(u8, "1234", bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 1 }));
+    try std.testing.expectEqualSlices(u8, "   666", bufPrintIntToSlice(buf, @as(u32, 666), 10, .lower, FormatOptions{ .width = 6 }));
+    try std.testing.expectEqualSlices(u8, "  1234", bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, .lower, FormatOptions{ .width = 6 }));
+    try std.testing.expectEqualSlices(u8, "1234", bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, .lower, FormatOptions{ .width = 1 }));
 
-    try std.testing.expectEqualSlices(u8, "+42", bufPrintIntToSlice(buf, @as(i32, 42), 10, false, FormatOptions{ .width = 3 }));
-    try std.testing.expectEqualSlices(u8, "-42", bufPrintIntToSlice(buf, @as(i32, -42), 10, false, FormatOptions{ .width = 3 }));
+    try std.testing.expectEqualSlices(u8, "+42", bufPrintIntToSlice(buf, @as(i32, 42), 10, .lower, FormatOptions{ .width = 3 }));
+    try std.testing.expectEqualSlices(u8, "-42", bufPrintIntToSlice(buf, @as(i32, -42), 10, .lower, FormatOptions{ .width = 3 }));
 }
 
-pub fn bufPrintIntToSlice(buf: []u8, value: anytype, base: u8, uppercase: bool, options: FormatOptions) []u8 {
-    return buf[0..formatIntBuf(buf, value, base, uppercase, options)];
+pub fn bufPrintIntToSlice(buf: []u8, value: anytype, base: u8, case: Case, options: FormatOptions) []u8 {
+    return buf[0..formatIntBuf(buf, value, base, case, options)];
 }
 
 pub fn comptimePrint(comptime fmt: []const u8, args: anytype) *const [count(fmt, args):0]u8 {
src/Compilation.zig
@@ -4009,7 +4009,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node
     });
     var digest_plus_flags: [digest.len + 2]u8 = undefined;
     digest_plus_flags[0..digest.len].* = digest;
-    assert(std.fmt.formatIntBuf(digest_plus_flags[digest.len..], stage1_flags_byte, 16, false, .{
+    assert(std.fmt.formatIntBuf(digest_plus_flags[digest.len..], stage1_flags_byte, 16, .lower, .{
         .width = 2,
         .fill = '0',
     }) == 2);
src/DepTokenizer.zig
@@ -1026,13 +1026,13 @@ fn hexDump16(out: anytype, offset: usize, bytes: []const u8) !void {
 
 fn printDecValue(out: anytype, value: u64, width: u8) !void {
     var buffer: [20]u8 = undefined;
-    const len = std.fmt.formatIntBuf(buffer[0..], value, 10, false, .{ .width = width, .fill = '0' });
+    const len = std.fmt.formatIntBuf(buffer[0..], value, 10, .lower, .{ .width = width, .fill = '0' });
     try out.writeAll(buffer[0..len]);
 }
 
 fn printHexValue(out: anytype, value: u64, width: u8) !void {
     var buffer: [16]u8 = undefined;
-    const len = std.fmt.formatIntBuf(buffer[0..], value, 16, false, .{ .width = width, .fill = '0' });
+    const len = std.fmt.formatIntBuf(buffer[0..], value, 16, .lower, .{ .width = width, .fill = '0' });
     try out.writeAll(buffer[0..len]);
 }
 
src/translate_c.zig
@@ -4146,7 +4146,7 @@ fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node {
     }
 
     const big: math.big.int.Const = .{ .limbs = limbs, .positive = true };
-    const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) {
+    const str = big.toStringAlloc(c.arena, 10, .lower) catch |err| switch (err) {
         error.OutOfMemory => return error.OutOfMemory,
     };
     const res = try Tag.integer_literal.create(c.arena, str);
@@ -5083,7 +5083,7 @@ fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 {
                         num += c - 'A' + 10;
                     },
                     else => {
-                        i += std.fmt.formatIntBuf(bytes[i..], num, 16, false, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
+                        i += std.fmt.formatIntBuf(bytes[i..], num, 16, .lower, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
                         num = 0;
                         if (c == '\\')
                             state = .Escape
@@ -5109,7 +5109,7 @@ fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 {
                     };
                     num += c - '0';
                 } else {
-                    i += std.fmt.formatIntBuf(bytes[i..], num, 16, false, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
+                    i += std.fmt.formatIntBuf(bytes[i..], num, 16, .lower, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
                     num = 0;
                     count = 0;
                     if (c == '\\')
@@ -5123,7 +5123,7 @@ fn zigifyEscapeSequences(ctx: *Context, m: *MacroCtx) ![]const u8 {
         }
     }
     if (state == .Hex or state == .Octal)
-        i += std.fmt.formatIntBuf(bytes[i..], num, 16, false, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
+        i += std.fmt.formatIntBuf(bytes[i..], num, 16, .lower, std.fmt.FormatOptions{ .fill = '0', .width = 2 });
     return bytes[0..i];
 }
 
src/Zir.zig
@@ -3231,7 +3231,7 @@ const Writer = struct {
             .limbs = limbs,
             .positive = true,
         };
-        const as_string = try big_int.toStringAlloc(self.gpa, 10, false);
+        const as_string = try big_int.toStringAlloc(self.gpa, 10, .lower);
         defer self.gpa.free(as_string);
         try stream.print("{s})", .{as_string});
     }
test/behavior/enum_with_members.zig
@@ -8,8 +8,8 @@ const ET = union(enum) {
 
     pub fn print(a: *const ET, buf: []u8) anyerror!usize {
         return switch (a.*) {
-            ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, fmt.FormatOptions{}),
-            ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, fmt.FormatOptions{}),
+            ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, .lower, fmt.FormatOptions{}),
+            ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, .lower, fmt.FormatOptions{}),
         };
     }
 };