I have a function that renders my DocObj to a fmt::Write:
impl DocObj {
fn render(&self, write: &mut dyn Write) -> io::Result<()>;
}
To implement fmt::Display, I want to write the same bytes to the fmt::Formatter, without copying and pasting code.
I'm a newbie to rust, and I've tried a variety of solutions, but nothing works so far.
Here's what I've tried:
Strategy 1: Implement Write trait for std::Formatter
Fails because rust won't let me implement a trait for a type in another crate. Ok.
Strategy 2: Create a little wrapper for std::Formatter that implements Write
Fails because I don't understand lifetimes or rust well enough yet.
struct DisplayWriter<'a> {
formatter: &'a fmt::Formatter<'a>
}
impl<'a> DisplayWriter<'a> {
fn from_formatter(aformatter: &'a mut fmt::Formatter<'a>) -> DisplayWriter<'a> {
DisplayWriter {formatter: aformatter}
}
}
impl<'a> io::Write for DisplayWriter<'a> {
fn write(&mut self, bytes: &[u8]) -> std::result::Result<usize, std::io::Error> {
use std::fmt::Write;
for c in bytes.iter() {
match self.formatter.write_char(*c as char) {
Err(err) => return Err(io::Error::new(io::ErrorKind::Other, err))
}
}
Ok(bytes.len())
}
fn flush(&mut self) -> std::result::Result<(), std::io::Error> { todo!() }
}
impl fmt::Display for DocObj {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let write = DisplayWriter::from_formatter(f);
match self.render(&mut write) {
Ok(_) => Ok(()),
Err(err) => Err(fmt::Error)
}
}
}
With this code, the compiler complains with the error message:
error[E0623]: lifetime mismatch
--> src\cos.rs:286:51
|
285 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
| -------------------
| |
| these two types are declared with different lifetimes...
286 | let write = DisplayWriter::from_formatter(f);
| ^ ...but data from `f` flows into `f` here
Some notes about my context:
- The bytes I want to display are not UTF-8 encoded. They are binary. I want to display one character for each byte. Therefore, any solution that does UTF encoding or decoding won't work in my context.
- The code is in a high performance loop, therefore I'd like to avoid allocating memory.
Thanks for your help!