Added filesystem abstraction
This commit is contained in:
parent
5610c19be4
commit
5ee22a06ee
69
fs/fs.go
Normal file
69
fs/fs.go
Normal 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
56
fsstuff/main.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user