Reputation: 65024
I want to implement some custom behavior for a printed struct. However, Go defines several different format verbs for structs, and I don't want to override all of them, just some of them.
I'm not sure how to do this in Go and it's more difficult because as far as I can tell you can't easily recover the original format string if all you have is a fmt.State
- you have to enumerate the flags and then call state.Flag(flag)
to see if each one is set.
Here's what I have so far - for unimplemented verbs, just create a second struct without a Format() argument and call fmt.Print on it. Is there a better way than this?
// Help values are returned by commands to indicate to the caller that it was
// called with a configuration that requested a help message rather than
// executing the command.
type Help struct {
Cmd string
}
// Fallback for unimplemented fmt verbs
type fmtHelp struct{ cmd string }
// Format satisfies the fmt.Formatter interface, print the help message for the
// command carried by h.
func (h *Help) Format(w fmt.State, v rune) {
switch v {
case 's':
printUsage(w, h.Cmd)
printHelp(w, h.Cmd)
case 'v':
if w.Flag('#') {
io.WriteString(w, "cli.Help{")
fmt.Fprintf(w, "%#v", h.Cmd)
io.WriteString(w, "}")
return
}
printUsage(w, h.Cmd)
printHelp(w, h.Cmd)
default:
// fall back to default struct formatter. TODO this does not handle
// flags
fmt.Fprintf(w, "%"+string(v), fmtHelp{h.Cmd})
}
}
Upvotes: 3
Views: 679
Reputation: 358
For fallback you would want this in your default case
default:
// Get the bypassed format directive
fmtDirective := fmt.FormatString(w, v)
fmt.Fprintf(f, fmtDirective, h.Cmd)
Check https://pkg.go.dev/fmt#FormatString
Upvotes: 0