Skip to content

Commit

Permalink
Ensure Pointer format is formatted correctly.
Browse files Browse the repository at this point in the history
  • Loading branch information
frozenlib committed May 30, 2024
1 parent 845843a commit 0e41049
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 5 deletions.
6 changes: 4 additions & 2 deletions parse-display-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,8 @@ impl DisplayFormat {
) -> Result<FormatArgs> {
let mut format_str = String::new();
let mut format_args = Vec::new();
let crate_path = context.crate_path();
let fmt_ref = quote!(#crate_path::helpers::FmtRef);
for p in &self.parts {
use DisplayFormatPart::*;
match p {
Expand All @@ -1102,7 +1104,7 @@ impl DisplayFormat {
format_str.push('}');
let format_arg =
context.format_arg(arg, format_spec, self.span, with, bounds, generics)?;
format_args.push(quote!(&#format_arg));
format_args.push(quote!(#fmt_ref(&#format_arg)));
}
}
}
Expand Down Expand Up @@ -1316,7 +1318,7 @@ impl<'a> DisplayContext<'a> {
DisplayContext::Struct { .. } => quote! { self.#key },
DisplayContext::Variant { .. } => {
let var = key.binding_var();
quote! { #var }
quote! { (*#var) }
}
DisplayContext::Field {
parent,
Expand Down
62 changes: 59 additions & 3 deletions parse-display/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::fmt::Display;
use core::fmt;

#[cfg(feature = "std")]
pub use super::helpers_std::*;
Expand All @@ -9,8 +9,8 @@ pub struct Formatted<'a, T: ?Sized, F: DisplayFormat<T>> {
pub value: &'a T,
pub format: F,
}
impl<T: ?Sized, F: DisplayFormat<T>> Display for Formatted<'_, T, F> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
impl<T: ?Sized, F: DisplayFormat<T>> fmt::Display for Formatted<'_, T, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.format.write(f, self.value)
}
}
Expand All @@ -21,3 +21,59 @@ where
{
fmt.parse(s)
}

pub struct FmtRef<'a, T: ?Sized>(pub &'a T);

impl<'a, T: ?Sized + fmt::Display> fmt::Display for FmtRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self.0, f)
}
}

impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for FmtRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(self.0, f)
}
}

impl<'a, T: ?Sized + fmt::Binary> fmt::Binary for FmtRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Binary::fmt(self.0, f)
}
}

impl<'a, T: ?Sized + fmt::Octal> fmt::Octal for FmtRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Octal::fmt(self.0, f)
}
}

impl<'a, T: ?Sized + fmt::LowerHex> fmt::LowerHex for FmtRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::LowerHex::fmt(self.0, f)
}
}

impl<'a, T: ?Sized + fmt::UpperHex> fmt::UpperHex for FmtRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::UpperHex::fmt(self.0, f)
}
}

impl<'a, T: ?Sized + fmt::Pointer> fmt::Pointer for FmtRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Pointer::fmt(self.0, f)
}
}

impl<'a, T: ?Sized + fmt::LowerExp> fmt::LowerExp for FmtRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::LowerExp::fmt(self.0, f)
}
}

impl<'a, T: ?Sized + fmt::UpperExp> fmt::UpperExp for FmtRef<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::UpperExp::fmt(&self.0, f)
}
}
23 changes: 23 additions & 0 deletions parse-display/tests/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,29 @@ fn escape() {
assert_display(Y, "}");
}

#[test]
fn struct_field_pointer() {
#[derive(Display)]
#[display("{0:p}")]
#[allow(unused)]
struct X(*const u32);
let p: *const u32 = &0;
assert_display(X(p), &format!("{p:p}"));
}

#[test]
fn enum_field_pointer() {
#[derive(Display)]
#[allow(unused)]
enum X {
#[display("{0:p}")]
A(*const u32),
}
let p: *const u32 = &0;
assert_display(X::A(p), &format!("{p:p}"));
}

#[track_caller]
fn assert_display<T: core::fmt::Display>(value: T, display: &str) {
let value_display = format!("{value}");
assert_eq!(value_display, display);
Expand Down

0 comments on commit 0e41049

Please sign in to comment.