ollie/fsedsl/help.go

72 lines
1.3 KiB
Go

package fsedsl
import (
"fmt"
"os"
"strings"
)
// GenerateHelp produces documentation from a filesystem spec tree.
// It walks the tree recursively and emits a line for each node with a Doc description.
func GenerateHelp[Ctx any](root FsNodeDecl[Ctx]) string {
return generateHelp(root, "")
}
func generateHelp[Ctx any](node FsNodeDecl[Ctx], prefix string) string {
var sb strings.Builder
path := node.Name
if prefix != "" {
path = prefix + "/" + node.Name
}
if node.Name == "/" {
path = ""
}
// Write this node's doc if it has one
if node.Desc != "" {
displayPath := path
if displayPath == "" {
displayPath = "/"
}
mode := node.Mode
if len(node.Children) > 0 || node.Bindings != nil {
mode = 0755 | os.ModeDir
}
fmt.Fprintf(&sb, "%-40s %s %s\n", displayPath, fmtMode(mode), node.Desc)
}
// Recurse into children
for _, child := range node.Children {
sb.WriteString(generateHelp(child, path))
}
return sb.String()
}
func fmtMode(m os.FileMode) string {
if m == 0 {
return "----"
}
var buf [4]byte
buf[0] = '-'
if m.IsDir() {
buf[0] = 'd'
}
buf[1] = 'r'
if m&0200 != 0 {
buf[1] = 'w'
}
if m&0400 != 0 {
buf[2] = 'r'
} else {
buf[2] = '-'
}
if m&0100 != 0 {
buf[3] = 'x'
} else {
buf[3] = '-'
}
return string(buf[:])
}