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) } } }