Is it possible to use println! without the Display trait?

Hi, I have a function of the form:

// In impl Ident {}
// `Interner` just stores a bunch of Strings
fn pretty_print(&self, f: &mut fmt::Formatter, intern: &Interner> -> fmt::Result {
  ...
}

Given that this function takes a fmt::Formatter and returns fmt::Result, I feel like there should be some way for std to interact with it but I can't find anything on the docs about that.

My best idea so far is:

impl<'id, 'in> fmt::Display for (&'id Ident, &'in Interner) {
   ...
}

println!("{}", (&ident, &intern));

but I wanted to check on here to make sure there wasn't a better solution

Thanks

println! uses Display so you can't really skip that. But I personally recommend this style:

impl Ident {
  // `Interner` just stores a bunch of Strings
  fn pretty_print<'a>(&'a self, intern: &'a Interner> -> impl Display + 'a {
    struct Helper<'a>(&'a Ident, &'a Interner);
    impl<'a> Display for Helper<'a> {
       // ...
    }

    Helper(self, intern)
  }
}

//...
println!("{}", ident.pretty_print(&intern));

This way, you don't make some random tuple type Display, and you can add a really_pretty_print later.

3 Likes

Yes, implement Display. In general, the only way to get a Formatter you can write to is to implement one of the formatting traits.

1 Like

This is a nice pattern, which would be made even nicer if Rust had a way to coerce closures directly into single-method impl Traits, Java-style. If there's a need to do this for several types, one could write a from_fn method to turn a closure into a Display type, the same way there's std::iter::from_fn for creating ad hoc iterators:

fn display_from_fn<F>(f: F) -> impl Display 
where
    F: FnMut(&mut Formatter) -> Result<(), Error>
{
    struct Helper(F);
    impl Display for Helper { ... }
    Helper(f)
}

fn pretty_print<'a>(&'a self, intern: &'a Interner> -> impl Display + 'a {
    display_from_fn(|fmt| {
        ...
    })
}
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.