107 lines
2.6 KiB
Go
107 lines
2.6 KiB
Go
package filesystem
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"time"
|
|
)
|
|
|
|
type FS interface {
|
|
ReadDir(path string) ([]os.FileInfo, error)
|
|
Read(path string) ([]byte, error)
|
|
Stat(path string) (os.FileInfo, error)
|
|
}
|
|
|
|
type FileInfo interface {
|
|
os.FileInfo
|
|
ContentType() string
|
|
Path() string
|
|
}
|
|
|
|
// File implements FileInfo
|
|
type File struct {
|
|
name string
|
|
size int64
|
|
mode os.FileMode
|
|
modTime time.Time
|
|
isDir bool
|
|
contentType string
|
|
path string
|
|
}
|
|
|
|
func (f File) Name() string { return f.name }
|
|
func (f File) Size() int64 { return f.size }
|
|
func (f File) Mode() os.FileMode { return f.mode }
|
|
func (f File) ModTime() time.Time { return f.modTime }
|
|
func (f File) IsDir() bool { return f.isDir }
|
|
func (f File) Sys() any { return nil }
|
|
func (f File) ContentType() string { return f.contentType }
|
|
func (f File) Path() string { return f.path }
|
|
|
|
type serializableFile struct {
|
|
Name string `json:"name"`
|
|
Size int64 `json:"size"`
|
|
Mode os.FileMode `json:"mode"`
|
|
ModTime time.Time `json:"modTime"`
|
|
IsDir bool `json:"isDir"`
|
|
ContentType string `json:"contentType"`
|
|
Path string `json:"path"`
|
|
}
|
|
|
|
// MarshalJSON implements json.Marshaler
|
|
func (f File) MarshalJSON() ([]byte, error) {
|
|
// Create a local shadow struct with exported fields for the JSON package
|
|
return json.Marshal(serializableFile{
|
|
Name: f.name,
|
|
Size: f.size,
|
|
Mode: f.mode,
|
|
ModTime: f.modTime,
|
|
IsDir: f.isDir,
|
|
ContentType: f.contentType,
|
|
Path: f.path,
|
|
})
|
|
}
|
|
|
|
// UnmarshalJSON implements json.Unmarshaler
|
|
func (f *File) UnmarshalJSON(data []byte) error {
|
|
// Define a shadow struct to capture the incoming JSON
|
|
shadow := serializableFile{}
|
|
|
|
if err := json.Unmarshal(data, &shadow); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Transfer values to the actual struct
|
|
f.name = shadow.Name
|
|
f.size = shadow.Size
|
|
f.mode = shadow.Mode
|
|
f.modTime = shadow.ModTime
|
|
f.isDir = shadow.IsDir
|
|
f.contentType = shadow.ContentType
|
|
f.path = shadow.Path
|
|
return nil
|
|
}
|
|
|
|
func ParseToFile(file os.FileInfo) File {
|
|
if fi, ok := file.(FileInfo); ok {
|
|
return File{
|
|
name: fi.Name(),
|
|
size: fi.Size(),
|
|
mode: fi.Mode(),
|
|
modTime: fi.ModTime(),
|
|
isDir: fi.IsDir(),
|
|
contentType: fi.ContentType(),
|
|
path: fi.Path(),
|
|
}
|
|
} else {
|
|
// Fallback if underlying impl returns generic os.FileInfo
|
|
return File{
|
|
name: file.Name(),
|
|
size: file.Size(),
|
|
mode: file.Mode(),
|
|
modTime: file.ModTime(),
|
|
isDir: file.IsDir(),
|
|
}
|
|
}
|
|
}
|