Added filesystem abstraction

This commit is contained in:
Brandon Dyck 2022-11-23 16:54:08 -07:00
parent 5610c19be4
commit 5ee22a06ee
2 changed files with 125 additions and 0 deletions

69
fs/fs.go Normal file
View File

@ -0,0 +1,69 @@
package fs
import (
"fmt"
"io"
"os"
"path/filepath"
)
type FS interface {
isFS()
}
type DirEntry struct {
Name string
FS FS
}
type Entries interface {
Get() []DirEntry
}
type Dir struct {
Entries
}
func (d Dir) isFS() {}
type Contents interface {
Get() io.Reader
}
type File struct {
Contents
}
func (f File) isFS() {}
func Realize(path string, f FS) error {
if f == nil {
return fmt.Errorf("cannot realize nil FS at %s", path)
}
switch t := f.(type) {
case File:
osf, err := os.Create(path)
if err != nil {
return fmt.Errorf("cannot create file %s: %w", path, err)
}
defer osf.Close()
_, err = io.Copy(osf, t.Get())
if err != nil {
return fmt.Errorf("cannot write file %s: %w", path, err)
}
case Dir:
err := os.Mkdir(path, 0666)
if err != nil {
return fmt.Errorf("cannot create dir %s: %w", path, err)
}
for _, child := range t.Get() {
err := Realize(filepath.Join(path, child.Name), child.FS)
if err != nil {
return err
}
}
default:
panic("unknown File type")
}
return nil
}

56
fsstuff/main.go Normal file
View File

@ -0,0 +1,56 @@
package main
import (
"io"
"log"
"strings"
"git.codemonkeysoftware.net/b/sbsqlitessgcms/fs"
)
type File string
func (f File) Get() io.Reader {
return strings.NewReader(string(f))
}
type Dir map[string]interface{}
func (d Dir) Get() []fs.DirEntry {
var entries []fs.DirEntry
for name, child := range d {
entry := fs.DirEntry{
Name: name,
}
switch t := child.(type) {
case File:
entry.FS = fs.File{Contents: t}
case Dir:
entry.FS = fs.Dir{Entries: t}
default:
panic("aw hell naw")
}
entries = append(entries, entry)
}
return entries
}
func main() {
dir := fs.Dir{
Entries: Dir{
"a": File("apple"),
"b": File("bootilicious"),
"c": File("curveball"),
"d": Dir{
"e": File("ectoplasm"),
"f": File("^&*("),
"g": File("grrrl power"),
"h": File("hellabyte"),
},
},
}
err := fs.Realize("./stuff", dir)
if err != nil {
log.Fatal(err)
}
}