github.com/artpar/rclone@v1.67.3/fs/direntries.go (about)

     1  package fs
     2  
     3  import "fmt"
     4  
     5  // DirEntries is a slice of Object or *Dir
     6  type DirEntries []DirEntry
     7  
     8  // Len is part of sort.Interface.
     9  func (ds DirEntries) Len() int {
    10  	return len(ds)
    11  }
    12  
    13  // Swap is part of sort.Interface.
    14  func (ds DirEntries) Swap(i, j int) {
    15  	ds[i], ds[j] = ds[j], ds[i]
    16  }
    17  
    18  // Less is part of sort.Interface.
    19  func (ds DirEntries) Less(i, j int) bool {
    20  	return CompareDirEntries(ds[i], ds[j]) < 0
    21  }
    22  
    23  // ForObject runs the function supplied on every object in the entries
    24  func (ds DirEntries) ForObject(fn func(o Object)) {
    25  	for _, entry := range ds {
    26  		o, ok := entry.(Object)
    27  		if ok {
    28  			fn(o)
    29  		}
    30  	}
    31  }
    32  
    33  // ForObjectError runs the function supplied on every object in the entries
    34  func (ds DirEntries) ForObjectError(fn func(o Object) error) error {
    35  	for _, entry := range ds {
    36  		o, ok := entry.(Object)
    37  		if ok {
    38  			err := fn(o)
    39  			if err != nil {
    40  				return err
    41  			}
    42  		}
    43  	}
    44  	return nil
    45  }
    46  
    47  // ForDir runs the function supplied on every Directory in the entries
    48  func (ds DirEntries) ForDir(fn func(dir Directory)) {
    49  	for _, entry := range ds {
    50  		dir, ok := entry.(Directory)
    51  		if ok {
    52  			fn(dir)
    53  		}
    54  	}
    55  }
    56  
    57  // ForDirError runs the function supplied on every Directory in the entries
    58  func (ds DirEntries) ForDirError(fn func(dir Directory) error) error {
    59  	for _, entry := range ds {
    60  		dir, ok := entry.(Directory)
    61  		if ok {
    62  			err := fn(dir)
    63  			if err != nil {
    64  				return err
    65  			}
    66  		}
    67  	}
    68  	return nil
    69  }
    70  
    71  // DirEntryType returns a string description of the DirEntry, either
    72  // "object", "directory" or "unknown type XXX"
    73  func DirEntryType(d DirEntry) string {
    74  	switch d.(type) {
    75  	case Object:
    76  		return "object"
    77  	case Directory:
    78  		return "directory"
    79  	}
    80  	return fmt.Sprintf("unknown type %T", d)
    81  }
    82  
    83  // CompareDirEntries returns 1 if a > b, 0 if a == b and -1 if a < b
    84  // If two dir entries have the same name, compare their types (directories are before objects)
    85  func CompareDirEntries(a, b DirEntry) int {
    86  	aName := a.Remote()
    87  	bName := b.Remote()
    88  
    89  	if aName > bName {
    90  		return 1
    91  	} else if aName < bName {
    92  		return -1
    93  	}
    94  
    95  	typeA := DirEntryType(a)
    96  	typeB := DirEntryType(b)
    97  
    98  	// same name, compare types
    99  	if typeA > typeB {
   100  		return 1
   101  	} else if typeA < typeB {
   102  		return -1
   103  	}
   104  
   105  	return 0
   106  }