package adapters import ( "os" "path/filepath" ) type LocalFsAdapter struct { root string } func (l LocalFsAdapter) readDir(path string) (FsResponse, error) { dirInfo, _ := os.Stat(path) entries, err := os.ReadDir(path) if err != nil { return FsResponse{}, err } out := make([]FsDirEntry, 0, len(entries)) for _, e := range entries { info, _ := e.Info() entryType := "dir" if !e.IsDir() { entryType = contentTypeFor(e.Name()) } out = append(out, FsDirEntry{ Name: e.Name(), Type: entryType, ModTime: info.ModTime(), }) } return FsResponse{ Dir: &FsDir{ Files: out, Name: ResponsePath(l.root, path), ModTime: dirInfo.ModTime(), }, }, nil } func (l LocalFsAdapter) readFile(path string) (FsResponse, error) { fi, err := os.Stat(path) if err != nil { return FsResponse{}, err } data, err := os.ReadFile(path) if err != nil { return FsResponse{}, err } return FsResponse{ File: &FsFile{ Name: ResponsePath(l.root, path), Type: contentTypeFor(path), ModTime: fi.ModTime(), Content: data, }, }, nil } func (l LocalFsAdapter) Read(path string) (FsResponse, error) { cleanRel, err := SafeRel(l.root, path) if err != nil { return FsResponse{}, err } target := filepath.Join(l.root, filepath.FromSlash(cleanRel)) fi, err := os.Stat(target) if err != nil { if os.IsNotExist(err) { return FsResponse{}, ErrNotFound } return FsResponse{}, err } if fi.IsDir() { return l.readDir(target) } return l.readFile(target) } func (LocalFsAdapter) Write(path string, content []byte) error { return nil } func NewLocalFsAdapter(root string) (FileAdapter, error) { return LocalFsAdapter{ root: root, }, nil }