DebugStruct, but for enums?

I've used DebugStruct previously to get custom {:?} outputs for structs. Now I'm faced with an enum:

enum AuthCred {
  UserPass { name: String, pass: String },
  Token(String)
}

We aren't allowed to log passphrases and raw tokens, but I want to be able to log some basic information about the authentication credentials, and log::debug!("Authentication credentials used: {ac:?}") is just so very convenient. To reconcile these two, if this were a struct, I would implement fmt::Debug manually and make the DebugStruct hardcode the pass field as ***, and the token I would probably just output as AuthCred::Token, or even - if I were in the mood to fight with project management, print the first two characters of the token, or something to that effect.

But in this case, I'm stuck with an enum. In theory I could move the UserPass into a struct, but that still leaves the Token case.

I could write a very manual Debug implementation, but I don't want to take away the ability of using {:#?} and get a pretty-formatted UserPass variant.

Are there any convenience tools, akin to DebugStruct, but for enum's? If not, how would one go about formatting AuthCred in a manner such that UserPass would get all the bells'n'whistles (i.e. support {:#?}), without needing to implement all that logic manually?

As a general tip you can place your caret on the derive macro and use the rust-analyser action "expand macro recursively at caret" (in vscode its in the ctrl+shift+p menu) to paste the derived Debug implementation and change it.

1 Like

you can treat enum variants as structs, which is essentially how the Debug derive macro in standard library is implemented.

match self {
	AuthCred::UserPass {
		name: name,
		pass: pass,
	} => f
		.debug_struct("UserPass")
		.field("name", &name)
		.field("pass", &"***")
		.finish(),
	AuthCred::Token(f0) => f.debug_tuple("Token").field(&"[redacted]").finish(),
}

I sometimes prefix the struct name with the enum name, i.e.

f.debug_tuple("AuthCred::Token").field(&"[redacted]").finish()
4 Likes