package paths import ( `io/fs` `os` `path/filepath` `time` `github.com/djherbis/times` `r00t2.io/goutils/bitmask` ) /* Match returns match (a ptr to a FsSearchResult if the specified path matches, otherwise nil), miss (ptr the specified path does not match, otherwise nil), and an fs.DirEntry and fs.FileInfo for path. d and/or fi may be nil. If err is not nil, it represents an unexpected error and as such, both match and miss should be nil. Match, miss, and err will all be nil if the filesystem object/path does not exist. */ func (f *FsSearchCriteria) Match(path string, d fs.DirEntry, fi fs.FileInfo) (match, miss *FsSearchResult, err error) { var typeMode fs.FileMode var m FsSearchResult var typeFilter *bitmask.MaskBit = bitmask.NewMaskBitExplicit(uint(f.TargetType)) m = FsSearchResult{ Path: path, DirEntry: d, FileInfo: fi, Criteria: f, } if f == nil { return } // A DirEntry can be created from a FileInfo but not vice versa. if m.FileInfo == nil { if m.DirEntry != nil { if m.FileInfo, err = m.DirEntry.Info(); err != nil { err = filterNoFileDir(err) if err != nil { return } } } else { if f.FollowSymlinks { if m.FileInfo, err = os.Stat(path); err != nil { err = filterNoFileDir(err) if err != nil { return } } } else { if m.FileInfo, err = os.Lstat(path); err != nil { err = filterNoFileDir(err) if err != nil { return } } } m.DirEntry = fs.FileInfoToDirEntry(m.FileInfo) } } if m.DirEntry == nil { m.DirEntry = fs.FileInfoToDirEntry(m.FileInfo) } if m.DirEntry == nil || m.FileInfo == nil { m.MissReason = MissNoMeta miss = &m return } if m.Times, err = times.Stat(path); err != nil { err = filterNoFileDir(err) if err != nil { return } } if f.PathPtrn != nil && !f.PathPtrn.MatchString(path) { m.MissReason = MissBadPath miss = &m return } if f.BasePtrn != nil && !f.BasePtrn.MatchString(filepath.Base(path)) { m.MissReason = MissBadBase miss = &m return } // age if f.Age != nil { if f.Now == nil { f.Now = new(time.Time) *f.Now = time.Now() } if !filterTimes(m.Times, f.Age, &f.AgeType, f.OlderThan, f.Now) { m.MissReason = MissBadTime miss = &m return } } // fs object type (file, dir, etc.) typeMode = m.FileInfo.Mode().Type() if typeMode == 0 && f.NoFiles { m.MissReason = MissFile miss = &m return } else if typeMode != 0 { if !typeFilter.HasFlag(bitmask.MaskBit(typeMode)) { m.MissReason = MissType miss = &m return } } // If it gets to here, it matches. match = &m return }