treeprint

package module
Version: v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 31, 2021 License: MIT Imports: 5 Imported by: 127

README

treeprint GoDoc test coverage

Package treeprint provides a simple ASCII tree composing tool.

SYSTEME FIGURE

If you are familiar with the tree utility that is a recursive directory listing command that produces a depth indented listing of files, then you have the idea of what it would look like.

On my system the command yields the following

 $ tree
.
├── LICENSE
├── README.md
├── treeprint.go
└── treeprint_test.go

0 directories, 4 files

and I'd like to have the same format for my Go data structures when I print them.

Installation

$ go get github.com/xlab/treeprint

Concept of work

The general idea is that you initialise a new tree with treeprint.New() and then add nodes and branches into it. Use AddNode() when you want add a node on the same level as the target or use AddBranch() when you want to go a level deeper. So tree.AddBranch().AddNode().AddNode() would create a new level with two distinct nodes on it. So tree.AddNode().AddNode() is a flat thing and tree.AddBranch().AddBranch().AddBranch() is a high thing. Use String() or Bytes() on a branch to render a subtree, or use it on the root to print the whole tree.

The utility will yield Unicode-friendly trees. The output is predictable and there is no platform-dependent exceptions, so if you have issues with displaying the tree in the console, all platform-related transformations can be done after the tree has been rendered: an example for Asian locales.

Use cases

When you want to render a complex data structure:
func main() {
    // to add a custom root name use `treeprint.NewWithRoot()` instead
    tree := treeprint.New()

    // create a new branch in the root
    one := tree.AddBranch("one")

    // add some nodes
    one.AddNode("subnode1").AddNode("subnode2")

    // create a new sub-branch
    one.AddBranch("two").
        AddNode("subnode1").AddNode("subnode2"). // add some nodes
        AddBranch("three"). // add a new sub-branch
        AddNode("subnode1").AddNode("subnode2") // add some nodes too

    // add one more node that should surround the inner branch
    one.AddNode("subnode3")

    // add a new node to the root
    tree.AddNode("outernode")

    fmt.Println(tree.String())
}

Will give you:

.
├── one
│   ├── subnode1
│   ├── subnode2
│   ├── two
│   │   ├── subnode1
│   │   ├── subnode2
│   │   └── three
│   │       ├── subnode1
│   │       └── subnode2
│   └── subnode3
└── outernode
Another case, when you have to make a tree where any leaf may have some meta-data (as tree is capable of it):
func main {
    // to add a custom root name use `treeprint.NewWithRoot()` instead
    tree := treeprint.New()

    tree.AddNode("Dockerfile")
    tree.AddNode("Makefile")
    tree.AddNode("aws.sh")
    tree.AddMetaBranch(" 204", "bin").
        AddNode("dbmaker").AddNode("someserver").AddNode("testtool")
    tree.AddMetaBranch(" 374", "deploy").
        AddNode("Makefile").AddNode("bootstrap.sh")
    tree.AddMetaNode("122K", "testtool.a")

    fmt.Println(tree.String())
}

Output:

.
├── Dockerfile
├── Makefile
├── aws.sh
├── [ 204]  bin
│   ├── dbmaker
│   ├── someserver
│   └── testtool
├── [ 374]  deploy
│   ├── Makefile
│   └── bootstrap.sh
└── [122K]  testtool.a
Iterating over the tree nodes
tree := New()

one := tree.AddBranch("one")
one.AddNode("one-subnode1").AddNode("one-subnode2")
one.AddBranch("two").AddNode("two-subnode1").AddNode("two-subnode2").
    AddBranch("three").AddNode("three-subnode1").AddNode("three-subnode2")
tree.AddNode("outernode")

// if you need to iterate over the whole tree
// call `VisitAll` from your top root node.
tree.VisitAll(func(item *node) {
    if len(item.Nodes) > 0 {
        // branch nodes
        fmt.Println(item.Value) // will output one, two, three
    } else {
        // leaf nodes
        fmt.Println(item.Value) // will output one-*, two-*, three-* and outernode
    }
})

Yay! So it works.

License

MIT

Documentation

Overview

Package treeprint provides a simple ASCII tree composing tool.

Index

Constants

This section is empty.

Variables

View Source
var IndentSize = 3

IndentSize is the number of spaces per tree level.

Functions

func Repr

func Repr(v interface{}) string

Types

type EdgeType

type EdgeType string
var (
	EdgeTypeLink EdgeType = "│"
	EdgeTypeMid  EdgeType = "├──"
	EdgeTypeEnd  EdgeType = "└──"
)

type FmtFunc

type FmtFunc func(name string, v interface{}) (string, bool)

type MetaValue

type MetaValue interface{}

MetaValue defines any meta value

type NodeVisitor added in v1.1.0

type NodeVisitor func(item *node)

NodeVisitor function type for iterating over nodes

type StructTreeOption

type StructTreeOption int
const (
	StructNameTree StructTreeOption = iota
	StructValueTree
	StructTagTree
	StructTypeTree
	StructTypeSizeTree
)

type Tree

type Tree interface {
	// AddNode adds a new node to a branch.
	AddNode(v Value) Tree
	// AddMetaNode adds a new node with meta value provided to a branch.
	AddMetaNode(meta MetaValue, v Value) Tree
	// AddBranch adds a new branch node (a level deeper).
	AddBranch(v Value) Tree
	// AddMetaBranch adds a new branch node (a level deeper) with meta value provided.
	AddMetaBranch(meta MetaValue, v Value) Tree
	// Branch converts a leaf-node to a branch-node,
	// applying this on a branch-node does no effect.
	Branch() Tree
	// FindByMeta finds a node whose meta value matches the provided one by reflect.DeepEqual,
	// returns nil if not found.
	FindByMeta(meta MetaValue) Tree
	// FindByValue finds a node whose value matches the provided one by reflect.DeepEqual,
	// returns nil if not found.
	FindByValue(value Value) Tree
	//  returns the last node of a tree
	FindLastNode() Tree
	// String renders the tree or subtree as a string.
	String() string
	// Bytes renders the tree or subtree as byteslice.
	Bytes() []byte

	SetValue(value Value)
	SetMetaValue(meta MetaValue)

	// VisitAll iterates over the tree, branches and nodes.
	// If need to iterate over the whole tree, use the root node.
	// Note this method uses a breadth-first approach.
	VisitAll(fn NodeVisitor)
}

Tree represents a tree structure with leaf-nodes and branch-nodes.

func FromStruct

func FromStruct(v interface{}, opt ...StructTreeOption) (Tree, error)

func FromStructWithMeta

func FromStructWithMeta(v interface{}, fmtFunc FmtFunc) (Tree, error)

func New

func New() Tree

New Generates new tree

func NewWithRoot added in v1.1.0

func NewWithRoot(root Value) Tree

NewWithRoot Generates new tree with the given root value

type Value

type Value interface{}

Value defines any value

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL