I just transitioned my code to use the new format! macros. I was happy to
get rid of all the .to_str() I had all over the place, but this turned out
not quite as I had expected.
I was hoping I'd be able to simply base on the ToStr trait to print
anything with {:s}. It turns out that actually there's a String trait with
an fmt function - Ok, that makes sense, as one can emit stuff piecewise
without having to pay the costs of creating an intermediate complete string.
But it turns out that the standard library hard-wires the implementation of
the String trait to use the Str trait, which has two functions - to_owned
and as_slice. I understand the motivation of as_slice for more efficient
formatting (though I don't see why it needs to provide to_owned, but
anyway). Ok, just a bit more boilerplate, I thought - but then I hit a wall.
The as_slice function requires returning a borrowed pointer whose lifetime
is specified by the caller. If my type has to_str which returns a ~str, I
can't really return a borrowed pointer to it (as the ~str will live too
short).
This problem is unique to the String trait. All the other traits (Bool,
Pointer, ...) just allow specifying the trait directly without getting too
clever with string slices. So... I cheated and added a LowerHex instance my
types instead of String (which conflicts with libstd) or Str (which I can't
implement). I now print my types with {:x} (I think of it as "user eXtended
format").
I know, this is pretty horrible... what is the "right thing" here? Using
{:s} and keep calling .to_str() everywhere?
A second, related problem, is formatting simple enums. It is easy to derive
ToStr for such enums, but this means I still need to say {:s} and
my_enum.to_str() - exactly what I hoped to avoid. And I really don't want
to manually specify a LowerHex or Str instance to each and every enum (it
is bad enough I need to do it for each of the relevant small-struct types).
If there was a, say, {:S} that was automatically available for everything
that had ToStr, then both problems would have been solved. {:s} would
remain a more efficient way to format things that were "actually" strings,
while {:S} would allow formatting things that could be "viewed as" strings.
Does that make sense?
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev