70 lines
1.0 KiB
Go
70 lines
1.0 KiB
Go
|
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
|
||
|
}
|