mirror of
https://github.com/kataras/iris.git
synced 2026-01-10 21:45:57 +00:00
add support for fs.FS, embed.FS (in addition of string and http.FileSystem) for i18n locales and view engine's templates
This commit is contained in:
@@ -5,17 +5,102 @@ import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// ResolveFS accepts a single input argument of any type
|
||||
// and tries to cast it to http.FileSystem.
|
||||
// and tries to cast it to fs.FS.
|
||||
//
|
||||
// It affects the view engine filesystem resolver
|
||||
// and the Application's API Builder's `HandleDir` method.
|
||||
// It affects the view engine's filesystem resolver.
|
||||
//
|
||||
// This package-level variable can be modified on initialization.
|
||||
var ResolveFS = func(fsOrDir interface{}) http.FileSystem {
|
||||
var ResolveFS = func(fsOrDir interface{}) fs.FS {
|
||||
if fsOrDir == nil {
|
||||
return noOpFS{}
|
||||
}
|
||||
|
||||
switch v := fsOrDir.(type) {
|
||||
case string:
|
||||
if v == "" {
|
||||
return noOpFS{}
|
||||
}
|
||||
return os.DirFS(v)
|
||||
case fs.FS:
|
||||
return v
|
||||
case http.FileSystem: // handles go-bindata.
|
||||
return &httpFS{v}
|
||||
default:
|
||||
panic(fmt.Errorf(`unexpected "fsOrDir" argument type of %T (string or fs.FS or embed.FS or http.FileSystem)`, v))
|
||||
}
|
||||
}
|
||||
|
||||
type noOpFS struct{}
|
||||
|
||||
func (fileSystem noOpFS) Open(name string) (fs.File, error) { return nil, nil }
|
||||
|
||||
// IsNoOpFS reports whether the given "fileSystem" is a no operation fs.
|
||||
func IsNoOpFS(fileSystem fs.FS) bool {
|
||||
_, ok := fileSystem.(noOpFS)
|
||||
return ok
|
||||
}
|
||||
|
||||
type httpFS struct {
|
||||
fs http.FileSystem
|
||||
}
|
||||
|
||||
func (f *httpFS) Open(name string) (fs.File, error) {
|
||||
if name == "." {
|
||||
name = "/"
|
||||
}
|
||||
|
||||
return f.fs.Open(filepath.ToSlash(name))
|
||||
}
|
||||
|
||||
func (f *httpFS) ReadDir(name string) ([]fs.DirEntry, error) {
|
||||
name = filepath.ToSlash(name)
|
||||
if name == "." {
|
||||
name = "/"
|
||||
}
|
||||
|
||||
file, err := f.fs.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
infos, err := file.Readdir(-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entries := make([]fs.DirEntry, 0, len(infos))
|
||||
for _, info := range infos {
|
||||
if info.IsDir() { // http file's does not return the whole tree, so read it.
|
||||
sub, err := f.ReadDir(info.Name())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entries = append(entries, sub...)
|
||||
continue
|
||||
}
|
||||
|
||||
entry := fs.FileInfoToDirEntry(info)
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
// ResolveHTTPFS accepts a single input argument of any type
|
||||
// and tries to cast it to http.FileSystem.
|
||||
//
|
||||
// It affects the Application's API Builder's `HandleDir` method.
|
||||
//
|
||||
// This package-level variable can be modified on initialization.
|
||||
var ResolveHTTPFS = func(fsOrDir interface{}) http.FileSystem {
|
||||
var fileSystem http.FileSystem
|
||||
switch v := fsOrDir.(type) {
|
||||
case string:
|
||||
|
||||
Reference in New Issue
Block a user