godebug: github.com/kylelemons/godebug/pretty Index | Examples | Files

package pretty

import "github.com/kylelemons/godebug/pretty"

Package pretty pretty-prints Go structures.

This package uses reflection to examine a Go value and can print out in a nice, aligned fashion. It supports three modes (normal, compact, and extended) for advanced use.

See the Reflect and Print examples for what the output looks like.

Index

Examples

Package Files

doc.go public.go reflect.go structure.go

Variables

var (
    // DefaultFormatter is the default set of overrides for stringification.
    DefaultFormatter = map[reflect.Type]interface{}{
        reflect.TypeOf(time.Time{}):          fmt.Sprint,
        reflect.TypeOf(net.IP{}):             fmt.Sprint,
        reflect.TypeOf((*error)(nil)).Elem(): fmt.Sprint,
    }

    // CompareConfig is the default configuration used for Compare.
    CompareConfig = &Config{
        Diffable:          true,
        IncludeUnexported: true,
        Formatter:         DefaultFormatter,
    }

    // DefaultConfig is the default configuration used for all other top-level functions.
    DefaultConfig = &Config{
        Formatter: DefaultFormatter,
    }
)

Default Config objects

func Compare Uses

func Compare(a, b interface{}) string

Compare returns a string containing a line-by-line unified diff of the values in a and b, using the CompareConfig.

Each line in the output is prefixed with '+', '-', or ' ' to indicate which side it's from. Lines from the a side are marked with '-', lines from the b side are marked with '+' and lines that are the same on both sides are marked with ' '.

Code:

type ShipManifest struct {
    Name     string
    Crew     map[string]string
    Androids int
    Stolen   bool
}

reported := &ShipManifest{
    Name: "Spaceship Heart of Gold",
    Crew: map[string]string{
        "Zaphod Beeblebrox": "Galactic President",
        "Trillian":          "Human",
        "Ford Prefect":      "A Hoopy Frood",
        "Arthur Dent":       "Along for the Ride",
    },
    Androids: 1,
    Stolen:   true,
}

expected := &ShipManifest{
    Name: "Spaceship Heart of Gold",
    Crew: map[string]string{
        "Trillian":      "Human",
        "Rowan Artosok": "Captain",
    },
    Androids: 1,
    Stolen:   false,
}

fmt.Println(pretty.Compare(reported, expected))

Output:

 {
  Name: "Spaceship Heart of Gold",
  Crew: {
-  Arthur Dent: "Along for the Ride",
-  Ford Prefect: "A Hoopy Frood",
+  Rowan Artosok: "Captain",
   Trillian: "Human",
-  Zaphod Beeblebrox: "Galactic President",
  },
  Androids: 1,
- Stolen: true,
+ Stolen: false,
 }

Code:

// Code under test:

type ShipManifest struct {
    Name     string
    Crew     map[string]string
    Androids int
    Stolen   bool
}

// AddCrew tries to add the given crewmember to the manifest.
AddCrew := func(m *ShipManifest, name, title string) {
    if m.Crew == nil {
        m.Crew = make(map[string]string)
    }
    m.Crew[title] = name
}

// Test function:
tests := []struct {
    desc        string
    before      *ShipManifest
    name, title string
    after       *ShipManifest
}{
    {
        desc:   "add first",
        before: &ShipManifest{},
        name:   "Zaphod Beeblebrox",
        title:  "Galactic President",
        after: &ShipManifest{
            Crew: map[string]string{
                "Zaphod Beeblebrox": "Galactic President",
            },
        },
    },
    {
        desc: "add another",
        before: &ShipManifest{
            Crew: map[string]string{
                "Zaphod Beeblebrox": "Galactic President",
            },
        },
        name:  "Trillian",
        title: "Human",
        after: &ShipManifest{
            Crew: map[string]string{
                "Zaphod Beeblebrox": "Galactic President",
                "Trillian":          "Human",
            },
        },
    },
    {
        desc: "overwrite",
        before: &ShipManifest{
            Crew: map[string]string{
                "Zaphod Beeblebrox": "Galactic President",
            },
        },
        name:  "Zaphod Beeblebrox",
        title: "Just this guy, you know?",
        after: &ShipManifest{
            Crew: map[string]string{
                "Zaphod Beeblebrox": "Just this guy, you know?",
            },
        },
    },
}

for _, test := range tests {
    AddCrew(test.before, test.name, test.title)
    if diff := pretty.Compare(test.before, test.after); diff != "" {
        t.Errorf("%s: post-AddCrew diff: (-got +want)\n%s", test.desc, diff)
    }
}

Output:

add first: post-AddCrew diff: (-got +want)
 {
  Name: "",
  Crew: {
-  Galactic President: "Zaphod Beeblebrox",
+  Zaphod Beeblebrox: "Galactic President",
  },
  Androids: 0,
  Stolen: false,
 }

add another: post-AddCrew diff: (-got +want)
 {
  Name: "",
  Crew: {
-  Human: "Trillian",
+  Trillian: "Human",
   Zaphod Beeblebrox: "Galactic President",
  },
  Androids: 0,
  Stolen: false,
 }

overwrite: post-AddCrew diff: (-got +want)
 {
  Name: "",
  Crew: {
-  Just this guy, you know?: "Zaphod Beeblebrox",
-  Zaphod Beeblebrox: "Galactic President",
+  Zaphod Beeblebrox: "Just this guy, you know?",
  },
  Androids: 0,
  Stolen: false,
 }

func Fprint Uses

func Fprint(w io.Writer, vals ...interface{}) (n int64, err error)

Fprint writes the representation of the given value to the writer according to the DefaultConfig.

func Print Uses

func Print(vals ...interface{})

Print writes the DefaultConfig representation of the given values to standard output.

Code:

type ShipManifest struct {
    Name     string
    Crew     map[string]string
    Androids int
    Stolen   bool
}

manifest := &ShipManifest{
    Name: "Spaceship Heart of Gold",
    Crew: map[string]string{
        "Zaphod Beeblebrox": "Galactic President",
        "Trillian":          "Human",
        "Ford Prefect":      "A Hoopy Frood",
        "Arthur Dent":       "Along for the Ride",
    },
    Androids: 1,
    Stolen:   true,
}

pretty.Print(manifest)

Output:

{Name:     "Spaceship Heart of Gold",
 Crew:     {Arthur Dent:       "Along for the Ride",
            Ford Prefect:      "A Hoopy Frood",
            Trillian:          "Human",
            Zaphod Beeblebrox: "Galactic President"},
 Androids: 1,
 Stolen:   true}

func Sprint Uses

func Sprint(vals ...interface{}) string

Sprint returns a string representation of the given value according to the DefaultConfig.

type Config Uses

type Config struct {
    // Verbosity options
    Compact  bool // One-line output. Overrides Diffable.
    Diffable bool // Adds extra newlines for more easily diffable output.

    // Field and value options
    IncludeUnexported   bool // Include unexported fields in output
    PrintStringers      bool // Call String on a fmt.Stringer
    PrintTextMarshalers bool // Call MarshalText on an encoding.TextMarshaler
    SkipZeroFields      bool // Skip struct fields that have a zero value.

    // Output transforms
    ShortList int // Maximum character length for short lists if nonzero.

    // Type-specific overrides
    //
    // Formatter maps a type to a function that will provide a one-line string
    // representation of the input value.  Conceptually:
    //   Formatter[reflect.TypeOf(v)](v) = "v as a string"
    //
    // Note that the first argument need not explicitly match the type, it must
    // merely be callable with it.
    //
    // When processing an input value, if its type exists as a key in Formatter:
    //   1) If the value is nil, no stringification is performed.
    //      This allows overriding of PrintStringers and PrintTextMarshalers.
    //   2) The value will be called with the input as its only argument.
    //      The function must return a string as its first return value.
    //
    // In addition to func literals, two common values for this will be:
    //   fmt.Sprint        (function) func Sprint(...interface{}) string
    //   Type.String         (method) func (Type) String() string
    //
    // Note that neither of these work if the String method is a pointer
    // method and the input will be provided as a value.  In that case,
    // use a function that calls .String on the formal value parameter.
    Formatter map[reflect.Type]interface{}
}

A Config represents optional configuration parameters for formatting.

Some options, notably ShortList, dramatically increase the overhead of pretty-printing a value.

Code:

pretty.DefaultFormatter[reflect.TypeOf(&net.IPNet{})] = func(n *net.IPNet) string {
    return fmt.Sprintf("CIDR=%s", n)
}
pretty.Print(&net.IPNet{
    IP:   net.IPv4(192, 168, 1, 100),
    Mask: net.CIDRMask(24, 32),
})

Output:

CIDR=192.168.1.100/24

Code:

pretty.DefaultFormatter[reflect.TypeOf(&net.IPNet{})] = fmt.Sprint
pretty.DefaultFormatter[reflect.TypeOf(net.HardwareAddr{})] = fmt.Sprint
pretty.Print(&net.IPNet{
    IP:   net.IPv4(192, 168, 1, 100),
    Mask: net.CIDRMask(24, 32),
})
pretty.Print(net.HardwareAddr{1, 2, 3, 4, 5, 6})

Output:

192.168.1.100/24
01:02:03:04:05:06

func (*Config) Compare Uses

func (cfg *Config) Compare(a, b interface{}) string

Compare returns a string containing a line-by-line unified diff of the values in got and want according to the cfg.

func (*Config) Fprint Uses

func (cfg *Config) Fprint(w io.Writer, vals ...interface{}) (n int64, err error)

Fprint writes the representation of the given value to the writer according to the cfg.

func (*Config) Print Uses

func (cfg *Config) Print(vals ...interface{})

Print writes the configured presentation of the given values to standard output.

func (*Config) Sprint Uses

func (cfg *Config) Sprint(vals ...interface{}) string

Sprint returns a string representation of the given value according to cfg.

Code:

type Pair [2]int
type Map struct {
    Name      string
    Players   map[string]Pair
    Obstacles map[Pair]string
}

m := Map{
    Name: "Rock Creek",
    Players: map[string]Pair{
        "player1": {1, 3},
        "player2": {0, -1},
    },
    Obstacles: map[Pair]string{
        Pair{0, 0}: "rock",
        Pair{2, 1}: "pond",
        Pair{1, 1}: "stream",
        Pair{0, 1}: "stream",
    },
}

// Specific output formats
compact := &pretty.Config{
    Compact: true,
}
diffable := &pretty.Config{
    Diffable: true,
}

// Print out a summary
fmt.Printf("Players: %s\n", compact.Sprint(m.Players))

// Print diffable output
fmt.Printf("Map State:\n%s", diffable.Sprint(m))

Output:

Players: {player1:[1,3],player2:[0,-1]}
Map State:
{
 Name: "Rock Creek",
 Players: {
  player1: [
   1,
   3,
  ],
  player2: [
   0,
   -1,
  ],
 },
 Obstacles: {
  [0,0]: "rock",
  [0,1]: "stream",
  [1,1]: "stream",
  [2,1]: "pond",
 },
}

Package pretty imports 11 packages (graph) and is imported by 20 packages. Updated 2017-07-17. Refresh now. Tools for package owners.