While you can use core::fmt::Write on byte slices, it is fundamentally for strings (it will also reject non-valid Unicode AFAIK). std::io::Write is for byte slices.
If we had a stack-string (ArrayString in arrayvec - Rust) in std, it would probably implement core::fmt::Write. But we don't.
I guess the "correct" API for this sort of thing would be to write into an &mut [u8] or even &mut [MaybeUninit<u8>], producing an &mut str (reborrowed from the &mut [u8]) that referred to just the written potion – that way you have a reference that knows it's pointing to UTF-8, pointing at the existing storage. But that isn't very compatible with the way that the Write traits work today.
The problem with doing an API like the one suggested in the original post is that it loses information about how much of the input has been written (and thus how much is valid UTF-8).