Skip to content

Commit 8b1d41d

Browse files
committed
Implement support for format specifiers
1 parent b2e86a4 commit 8b1d41d

File tree

1 file changed

+49
-13
lines changed

1 file changed

+49
-13
lines changed

source/geod24/bitblob.d

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module geod24.bitblob;
1717

1818
static import std.ascii;
1919
import std.algorithm.iteration : each, map;
20+
import std.format;
2021
import std.range;
2122
import std.utf;
2223

@@ -64,26 +65,58 @@ public struct BitBlob (size_t Size)
6465
6566
Format the hash as a lowercase hex string
6667
67-
Used by `std.format`.
68+
Used by `std.format` and other formatting primitives.
6869
Does not allocate/throw if the sink does not allocate/throw.
6970
71+
See_Also:
72+
https://issues.dlang.org/show_bug.cgi?id=21722
73+
74+
Params:
75+
sink = A delegate that can be called repeatedly to accumulate the data
76+
fmt = The format string used. Default to `%s`.
77+
7078
***************************************************************************/
7179

7280
public void toString (scope void delegate(const(char)[]) @safe sink) const
81+
{
82+
FormatSpec!char spec;
83+
this.toString(sink, spec);
84+
}
85+
86+
/// Ditto
87+
public void toString (scope void delegate(const(char)[]) @safe sink,
88+
scope const ref FormatSpec!char spec) const
7389
{
7490
/// Used for formatting
7591
static immutable LHexDigits = `0123456789abcdef`;
92+
static immutable HHexDigits = `0123456789ABCDEF`;
7693

77-
sink("0x");
78-
char[2] data;
79-
// retro because the data is stored in little endian
80-
this.data[].retro.each!(
81-
(bin)
82-
{
83-
data[0] = LHexDigits[bin >> 4];
84-
data[1] = LHexDigits[(bin & 0b0000_1111)];
85-
sink(data);
86-
});
94+
void formatDigits (immutable string hex_digits)
95+
{
96+
char[2] data;
97+
// retro because the data is stored in little endian
98+
this.data[].retro.each!(
99+
(bin)
100+
{
101+
data[0] = hex_digits[bin >> 4];
102+
data[1] = hex_digits[(bin & 0b0000_1111)];
103+
sink(data);
104+
});
105+
}
106+
107+
switch (spec.spec)
108+
{
109+
case 'X':
110+
formatDigits(HHexDigits);
111+
break;
112+
case 's':
113+
default:
114+
sink("0x");
115+
goto case;
116+
case 'x':
117+
formatDigits(LHexDigits);
118+
break;
119+
}
87120
}
88121

89122
/***************************************************************************
@@ -277,10 +310,14 @@ pure @safe nothrow @nogc unittest
277310
/// Test toString
278311
unittest
279312
{
280-
import std.format;
313+
import std.string : toUpper;
314+
281315
alias Hash = BitBlob!32;
282316
Hash gen1 = GenesisBlockHashStr;
283317
assert(format("%s", gen1) == GenesisBlockHashStr);
318+
assert(format("%x", gen1) == GenesisBlockHashStr[2 .. $]);
319+
assert(format("%X", gen1) == GenesisBlockHashStr[2 .. $].toUpper());
320+
assert(format("%w", gen1) == GenesisBlockHashStr);
284321
assert(gen1.toString() == GenesisBlockHashStr);
285322
assert(Hash(gen1.toString()) == gen1);
286323
assert(Hash.fromString(gen1.toString()) == gen1);
@@ -290,7 +327,6 @@ unittest
290327
unittest
291328
{
292329
import core.memory;
293-
import std.format;
294330
alias Hash = BitBlob!32;
295331

296332
Hash gen1 = GenesisBlockHashStr;

0 commit comments

Comments
 (0)