github.com/v2fly/tools@v0.100.0/godoc/vfs/fs.go (about) 1 // Copyright 2021 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build go1.16 6 // +build go1.16 7 8 package vfs 9 10 import ( 11 "io/fs" 12 "os" 13 "path" 14 "strings" 15 ) 16 17 // FromFS converts an fs.FS to the FileSystem interface. 18 func FromFS(fsys fs.FS) FileSystem { 19 return &fsysToFileSystem{fsys} 20 } 21 22 type fsysToFileSystem struct { 23 fsys fs.FS 24 } 25 26 func (f *fsysToFileSystem) fsPath(name string) string { 27 name = path.Clean(name) 28 if name == "/" { 29 return "." 30 } 31 return strings.TrimPrefix(name, "/") 32 } 33 34 func (f *fsysToFileSystem) Open(name string) (ReadSeekCloser, error) { 35 file, err := f.fsys.Open(f.fsPath(name)) 36 if err != nil { 37 return nil, err 38 } 39 if rsc, ok := file.(ReadSeekCloser); ok { 40 return rsc, nil 41 } 42 return &noSeekFile{f.fsPath(name), file}, nil 43 } 44 45 func (f *fsysToFileSystem) Lstat(name string) (os.FileInfo, error) { 46 return fs.Stat(f.fsys, f.fsPath(name)) 47 } 48 49 func (f *fsysToFileSystem) Stat(name string) (os.FileInfo, error) { 50 return fs.Stat(f.fsys, f.fsPath(name)) 51 } 52 53 func (f *fsysToFileSystem) RootType(name string) RootType { return "" } 54 55 func (f *fsysToFileSystem) ReadDir(name string) ([]os.FileInfo, error) { 56 dirs, err := fs.ReadDir(f.fsys, f.fsPath(name)) 57 var infos []os.FileInfo 58 for _, d := range dirs { 59 info, err1 := d.Info() 60 if err1 != nil { 61 if err == nil { 62 err = err1 63 } 64 continue 65 } 66 infos = append(infos, info) 67 } 68 return infos, err 69 } 70 71 func (f *fsysToFileSystem) String() string { return "io/fs" } 72 73 type noSeekFile struct { 74 path string 75 fs.File 76 } 77 78 func (f *noSeekFile) Seek(offset int64, whence int) (int64, error) { 79 return 0, &fs.PathError{Op: "seek", Path: f.path, Err: fs.ErrInvalid} 80 }