On 09/05/2011 04:30 AM, kenji hara wrote:
I have already posted some pull requests around formatting.
#126 Improve std.format.formatValue (-> already merged)
#230 Issue 6448 - writef("%05d", BigInt) problem (-> already merged)
#231 Issue 6595 - std.string.format() and sformat() are obsolete
#235 Change toString signature taking sink
#236 to!SomeString should use formatValue
After merging them, we can use const void toString(scope void
delegate(const(char)[]) sink, ...) at all.
Great. Thank you.
If you need custom formatting with class/struct, you can define
toString taking sink.
class UserClass {
string name;
double value;
// taking sink and formatStr version
const void toString(scope void delegate(const(char)[]) sink,
string formatStr) {
formattedWrite(sink, "{%s %s}", name, value)
}
// taking sink and FormatSpec!char version, more efficiently than above
const void toString(scope void delegate(const(char)[]) sink,
FormatSpec!char f) {
std.range.put(sink, '{');
std.range.put(sink, name);
std.range.put(sink, ' ');
formatValue(sink, value, f);
// To through spec to 'value' field formatting, then
support %s, %g, %a ...
std.range.put(sink, '}');
}
}
And if you need heapfied formatting, you can write like follows:
auto obj = new UserClass("name", 1.0);
assert(std.conv.to!string(obj) == "{name 1.0}"); // used Appender +
formatValue internally
appender is slower than direct appending unless you are dealing with
quite long arrays. I am not sure it is a good fit for this case, because
the strings returned are usually quite short.
assert(std.string.format("%s", obj) == "{name 1.0}"); // ditto
, and if you really need formatting into stack-allocated buffer:
char[20] buf;
char[] result = std.string.sformat(sink[], "%s", obj); // When
buf.length is insufficient, FormatError is thrown
I think throwing an Error might be overkill, an Exception should suffice.
assert(result == "{name, 1.0}");
Kenji Hara