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 }