Huon's suggestion of using fmt::Default is what I would suggest as well. The behavior you're running into is actually a known "feature" of rust today. You'll find in the fmt module "impl<T: Str> String for T", and because of this the compiler will not allow you to implement String for any type specifically. It was not the intention of the String trait to force you to implement Str (because as you've discovered, it's very difficult).
That being said, I've been using fmt::Default extensively inside of rustdoc, so it's certainly very "usable". I'm still unsure if the trait implementation behavior for String is a bug or a feature, but perhaps we'll relax the rules soon to allow implementations of String for other types as well. On Mon, Sep 30, 2013 at 11:13 PM, Oren Ben-Kiki <[email protected]> wrote: > 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 > _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
