mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 15:42:25 -05:00 
			
		
		
		
	This allows for building GoToSocial with [SQLite transpiled to WASM](https://github.com/ncruces/go-sqlite3) and accessed through [Wazero](https://wazero.io/).
		
			
				
	
	
		
			99 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package sysfs
 | |
| 
 | |
| import (
 | |
| 	"io/fs"
 | |
| 	"os"
 | |
| 
 | |
| 	experimentalsys "github.com/tetratelabs/wazero/experimental/sys"
 | |
| 	"github.com/tetratelabs/wazero/internal/platform"
 | |
| 	"github.com/tetratelabs/wazero/sys"
 | |
| )
 | |
| 
 | |
| func DirFS(dir string) experimentalsys.FS {
 | |
| 	return &dirFS{
 | |
| 		dir:        dir,
 | |
| 		cleanedDir: ensureTrailingPathSeparator(dir),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func ensureTrailingPathSeparator(dir string) string {
 | |
| 	if !os.IsPathSeparator(dir[len(dir)-1]) {
 | |
| 		return dir + string(os.PathSeparator)
 | |
| 	}
 | |
| 	return dir
 | |
| }
 | |
| 
 | |
| // dirFS is not exported because the input fields must be maintained together.
 | |
| // This is likely why os.DirFS doesn't, either!
 | |
| type dirFS struct {
 | |
| 	experimentalsys.UnimplementedFS
 | |
| 
 | |
| 	dir string
 | |
| 	// cleanedDir is for easier OS-specific concatenation, as it always has
 | |
| 	// a trailing path separator.
 | |
| 	cleanedDir string
 | |
| }
 | |
| 
 | |
| // String implements fmt.Stringer
 | |
| func (d *dirFS) String() string {
 | |
| 	return d.dir
 | |
| }
 | |
| 
 | |
| // OpenFile implements the same method as documented on sys.FS
 | |
| func (d *dirFS) OpenFile(path string, flag experimentalsys.Oflag, perm fs.FileMode) (experimentalsys.File, experimentalsys.Errno) {
 | |
| 	return OpenOSFile(d.join(path), flag, perm)
 | |
| }
 | |
| 
 | |
| // Lstat implements the same method as documented on sys.FS
 | |
| func (d *dirFS) Lstat(path string) (sys.Stat_t, experimentalsys.Errno) {
 | |
| 	return lstat(d.join(path))
 | |
| }
 | |
| 
 | |
| // Stat implements the same method as documented on sys.FS
 | |
| func (d *dirFS) Stat(path string) (sys.Stat_t, experimentalsys.Errno) {
 | |
| 	return stat(d.join(path))
 | |
| }
 | |
| 
 | |
| // Mkdir implements the same method as documented on sys.FS
 | |
| func (d *dirFS) Mkdir(path string, perm fs.FileMode) (errno experimentalsys.Errno) {
 | |
| 	err := os.Mkdir(d.join(path), perm)
 | |
| 	if errno = experimentalsys.UnwrapOSError(err); errno == experimentalsys.ENOTDIR {
 | |
| 		errno = experimentalsys.ENOENT
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // Readlink implements the same method as documented on sys.FS
 | |
| func (d *dirFS) Readlink(path string) (string, experimentalsys.Errno) {
 | |
| 	// Note: do not use syscall.Readlink as that causes race on Windows.
 | |
| 	// In any case, syscall.Readlink does almost the same logic as os.Readlink.
 | |
| 	dst, err := os.Readlink(d.join(path))
 | |
| 	if err != nil {
 | |
| 		return "", experimentalsys.UnwrapOSError(err)
 | |
| 	}
 | |
| 	return platform.ToPosixPath(dst), 0
 | |
| }
 | |
| 
 | |
| // Rmdir implements the same method as documented on sys.FS
 | |
| func (d *dirFS) Rmdir(path string) experimentalsys.Errno {
 | |
| 	return rmdir(d.join(path))
 | |
| }
 | |
| 
 | |
| // Utimens implements the same method as documented on sys.FS
 | |
| func (d *dirFS) Utimens(path string, atim, mtim int64) experimentalsys.Errno {
 | |
| 	return utimens(d.join(path), atim, mtim)
 | |
| }
 | |
| 
 | |
| func (d *dirFS) join(path string) string {
 | |
| 	switch path {
 | |
| 	case "", ".", "/":
 | |
| 		if d.cleanedDir == "/" {
 | |
| 			return "/"
 | |
| 		}
 | |
| 		// cleanedDir includes an unnecessary delimiter for the root path.
 | |
| 		return d.cleanedDir[:len(d.cleanedDir)-1]
 | |
| 	}
 | |
| 	// TODO: Enforce similar to safefilepath.FromFS(path), but be careful as
 | |
| 	// relative path inputs are allowed. e.g. dir or path == ../
 | |
| 	return d.cleanedDir + path
 | |
| }
 |