Files
zurg/internal/fs/node.go
2024-05-06 10:48:01 +02:00

88 lines
2.0 KiB
Go

package fs
import (
"strings"
cmap "github.com/orcaman/concurrent-map/v2"
)
// FileNode represents a directory or a file. If IsDir is true, Children is used.
type FileNode struct {
Name string
IsDir bool
Children cmap.ConcurrentMap[string, *FileNode]
}
// NewFileNode creates a new FileNode, initializing the concurrent map if it is a directory.
func NewFileNode(name string, isDir bool) *FileNode {
node := &FileNode{
Name: name,
IsDir: isDir,
}
if isDir {
node.Children = cmap.New[*FileNode]()
}
return node
}
// AddChild adds a child node to a directory node.
func (n *FileNode) AddChild(child *FileNode) {
if n.IsDir {
n.Children.Set(child.Name, child)
}
}
// AddPath adds a path to the file system like mkdir -p.
func (n *FileNode) MakeDirectoryWithPath(path string) {
currentNode := n
for _, part := range SplitPath(path) {
child, ok := currentNode.Children.Get(part)
if !ok {
child = NewFileNode(part, true)
currentNode.AddChild(child)
}
currentNode = child
}
}
// AddChildToPath adds a child to a path in the file system. Path should be an existing directory.
func (n *FileNode) AddChildToPath(path string, child *FileNode) {
parent := n.GetFileNode(path)
if parent != nil && parent.IsDir {
parent.AddChild(child)
}
}
// ListFiles returns a list of files in the file system.
func (n *FileNode) ListFiles() []*FileNode {
var files []*FileNode
n.Children.IterCb(func(key string, value *FileNode) {
files = append(files, value)
})
return files
}
// GetFileNode returns the FileNode of the given path.
func (n *FileNode) GetFileNode(path string) *FileNode {
currentNode := n
for _, part := range SplitPath(path) {
child, ok := currentNode.Children.Get(part)
if !ok {
return nil
}
currentNode = child
}
return currentNode
}
// SplitPath splits a path into its parts.
func SplitPath(path string) []string {
var parts []string
for _, part := range strings.Split(path, "/") {
if part != "" {
parts = append(parts, part)
}
}
return parts
}