77 lines
1.4 KiB
Go
77 lines
1.4 KiB
Go
package tree
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
|
|
"dirmd/internal/walker"
|
|
)
|
|
|
|
type Node struct {
|
|
Name string
|
|
IsDir bool
|
|
Children map[string]*Node
|
|
}
|
|
|
|
func Build(entries []walker.Entry) *Node {
|
|
root := &Node{IsDir: true, Children: make(map[string]*Node)}
|
|
|
|
for _, e := range entries {
|
|
parts := strings.Split(e.RelPath, "/")
|
|
cur := root
|
|
|
|
for i, part := range parts {
|
|
isLeaf := i == len(parts)-1
|
|
if _, ok := cur.Children[part]; !ok {
|
|
cur.Children[part] = &Node{Name: part, IsDir: !isLeaf, Children: make(map[string]*Node)}
|
|
}
|
|
cur = cur.Children[part]
|
|
}
|
|
}
|
|
|
|
return root
|
|
}
|
|
|
|
func Render(root *Node, rootName string) string {
|
|
var sb strings.Builder
|
|
sb.WriteString(rootName)
|
|
sb.WriteString("/\n")
|
|
renderNode(&sb, root, "")
|
|
return sb.String()
|
|
}
|
|
|
|
func renderNode(sb *strings.Builder, node *Node, prefix string) {
|
|
keys := make([]string, 0, len(node.Children))
|
|
for k := range node.Children {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
for i, key := range keys {
|
|
child := node.Children[key]
|
|
isLast := i == len(keys)-1
|
|
|
|
if isLast {
|
|
sb.WriteString(prefix + "└── ")
|
|
} else {
|
|
sb.WriteString(prefix + "├── ")
|
|
}
|
|
|
|
sb.WriteString(child.Name)
|
|
if child.IsDir {
|
|
sb.WriteString("/")
|
|
}
|
|
sb.WriteString("\n")
|
|
|
|
if child.IsDir {
|
|
newPrefix := prefix
|
|
if isLast {
|
|
newPrefix += " "
|
|
} else {
|
|
newPrefix += "│ "
|
|
}
|
|
renderNode(sb, child, newPrefix)
|
|
}
|
|
}
|
|
}
|