Maybe there should be a `osformat!` macro

I think it is a common task to manipulate file names and paths to append numbers or extra extensions, etc. I have encountered this problem myself a few times, and also found this post on StackOverflow about the issue.

From code I've seen, the commonly used solution is to use format! with .to_str().unwrap() on the path's parts. This is understandable, because format! won't work directly on &OsStr. Such pattern probably makes a lot of rust code break when used with invalid UTF-8 paths.

I myself try to avoid calling .to_str() on OsStr, and I usually .clone()/.to_owned(), then append the modifications in-place with .push(), which is much more cumbersome and uglier.

I think there should be in std a format-like macro that can format both Display and AsRef<OsStr>, but outputs OsString instead of String, thus providing a little friendlier experience with OsStr and Path.

What do you think? Is it feasible? A good idea?

1 Like

It seems it isn't even possible to implement this without compiler support.

There’s a Write impl so it should be possible to use the write! macro with it. Then it should be trivial to write a wrapper macro that creates an empty OsString and write!s the provided arguments to it.

Ah, but that doesn’t handle formatting in OsStr’s.

1 Like

Do check out format_bytes. It seems particularly relevant.

While formatting with/into bytestrings instead of utf8strings is certainly useful, it's not of any real help for OS strings, since those are (currently[1]) (mostly[2]) opaque and non introspectable.

Thus the only way the format_bytes crate is relevant is in that it's another crate which has implemented a custom format_args![3] macro.


  1. There's been some talk of allowing bytewise views more widely (i.e. specifying the use of WTF-8 or OMG-WTF-8 on Windows). ↩︎

  2. Unixy platforms have to/from bytes conversions via OsStrExt and it's known guaranteed that OS strings' encoding is a superset of UTF-8 because of the provided by-ref conversions between str and OsStr. ↩︎

  3. Yes, technically they implemented a write!, not a format_args!. Morally, though, write!($w, $($args)*) is just $w.write_fmt(format_args!($($args)*)). ↩︎

This article, linked from the format_bytes documentation, seems particularly relevant.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.