github.com/grailbio/base@v0.0.11/file/fsnode/fileinfo.go (about)

     1  package fsnode
     2  
     3  import (
     4  	"os"
     5  	"time"
     6  )
     7  
     8  // FileInfo implements os.FileInfo. Instances are immutable but convenient
     9  // copy-and-set methods are provided for some fields. FileInfo implements
    10  // (T).Info, so implementations of T can conveniently embed a FileInfo for
    11  // simple cases, e.g. if the information is immutable.
    12  type FileInfo struct {
    13  	name         string
    14  	size         int64
    15  	mode         os.FileMode
    16  	mod          time.Time
    17  	sys          interface{}
    18  	cacheableFor time.Duration
    19  }
    20  
    21  // Info implements (T).Info.
    22  func (fi FileInfo) Info() os.FileInfo {
    23  	return fi
    24  }
    25  
    26  // NewDirInfo constructs FileInfo for a directory.
    27  // Default ModePerm is 0555 (r-xr-xr-x). Other defaults are zero.
    28  func NewDirInfo(name string) FileInfo { return FileInfo{name: name, mode: os.ModeDir | 0555} }
    29  
    30  // NewRegInfo constructs FileInfo for a regular file.
    31  // Default ModePerm is 0444 (r--r--r--). Other defaults are zero.
    32  func NewRegInfo(name string) FileInfo { return FileInfo{name: name, mode: 0444} }
    33  
    34  // NewSymlinkInfo constructs FileInfo for a symlink.
    35  //
    36  // Create a symlink by using this FileInfo with a Leaf whose contents are the target path.
    37  // The path may be relative or absolute.
    38  func NewSymlinkInfo(name string) FileInfo {
    39  	return FileInfo{
    40  		name: name,
    41  		// Note: Symlinks don't need permissions. From `man 7 symlink`:
    42  		//   On Linux, the permissions of a symbolic link are not used in any operations; ...
    43  		// And on macOS:
    44  		//   Of these, only the flags are used by the system; the access permissions and
    45  		//   ownership are ignored.
    46  		mode: os.ModeSymlink,
    47  	}
    48  }
    49  
    50  // CopyFileInfo constructs FileInfo with the same public fields as info.
    51  // It copies cacheability if available.
    52  func CopyFileInfo(info os.FileInfo) FileInfo {
    53  	return FileInfo{
    54  		name:         info.Name(),
    55  		size:         info.Size(),
    56  		mode:         info.Mode(),
    57  		mod:          info.ModTime(),
    58  		sys:          info.Sys(),
    59  		cacheableFor: CacheableFor(info),
    60  	}
    61  }
    62  
    63  func (f FileInfo) Name() string                { return f.name }
    64  func (f FileInfo) Size() int64                 { return f.size }
    65  func (f FileInfo) Mode() os.FileMode           { return f.mode }
    66  func (f FileInfo) ModTime() time.Time          { return f.mod }
    67  func (f FileInfo) IsDir() bool                 { return f.mode&os.ModeDir != 0 }
    68  func (f FileInfo) Sys() interface{}            { return f.sys }
    69  func (f FileInfo) CacheableFor() time.Duration { return f.cacheableFor }
    70  
    71  func (f FileInfo) WithName(name string) FileInfo {
    72  	cp := f
    73  	cp.name = name
    74  	return cp
    75  }
    76  func (f FileInfo) WithSize(size int64) FileInfo {
    77  	cp := f
    78  	cp.size = size
    79  	return cp
    80  }
    81  func (f FileInfo) WithModePerm(perm os.FileMode) FileInfo {
    82  	cp := f
    83  	cp.mode = (perm & os.ModePerm) | (cp.mode &^ os.ModePerm)
    84  	return cp
    85  }
    86  func (f FileInfo) WithModeType(modeType os.FileMode) FileInfo {
    87  	cp := f
    88  	cp.mode = (modeType & os.ModeType) | (cp.mode &^ os.ModeType)
    89  	return cp
    90  }
    91  func (f FileInfo) WithModTime(mod time.Time) FileInfo {
    92  	cp := f
    93  	cp.mod = mod
    94  	return cp
    95  }
    96  func (f FileInfo) WithSys(sys interface{}) FileInfo {
    97  	cp := f
    98  	cp.sys = sys
    99  	return cp
   100  }
   101  func (f FileInfo) WithCacheableFor(d time.Duration) FileInfo {
   102  	cp := f
   103  	cp.cacheableFor = d
   104  	return cp
   105  }
   106  
   107  func (f FileInfo) Equal(g FileInfo) bool {
   108  	if !f.mod.Equal(g.mod) {
   109  		return false
   110  	}
   111  	f.mod = g.mod
   112  	return f == g
   113  }