github.com/wolfi-dev/wolfictl@v0.16.11/pkg/configs/selection.go (about)

     1  package configs
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	"github.com/samber/lo"
     8  )
     9  
    10  // A Selection is a view into an Index's configuration (type T) entries. The
    11  // selection can expose anywhere from zero entries up to all the index's
    12  // entries. A selection allows the caller to chain methods to further constrain
    13  // the selection and to perform operations on each item in the selection.
    14  type Selection[T Configuration] struct {
    15  	entries []Entry[T]
    16  	index   *Index[T]
    17  }
    18  
    19  // WhereName filters the selection down to entries whose name match the given
    20  // parameter.
    21  func (s Selection[T]) WhereName(name string) Selection[T] {
    22  	return s.Where(func(e Entry[T]) bool {
    23  		cfg := e.Configuration()
    24  		if cfg == nil {
    25  			return false
    26  		}
    27  
    28  		return name == (*cfg).Name()
    29  	})
    30  }
    31  
    32  // WhereFilePath filters the selection down to entries whose configuration file
    33  // path match the given parameter.
    34  func (s Selection[T]) WhereFilePath(p string) Selection[T] {
    35  	return s.Where(func(e Entry[T]) bool {
    36  		return p == e.getPath()
    37  	})
    38  }
    39  
    40  // Where filters the selection down to entries for which the given condition is
    41  // true.
    42  func (s Selection[T]) Where(condition func(Entry[T]) bool) Selection[T] {
    43  	var entries []Entry[T]
    44  	for _, e := range s.entries {
    45  		if condition(e) {
    46  			entries = append(entries, e)
    47  		}
    48  	}
    49  
    50  	return Selection[T]{
    51  		entries: entries,
    52  		index:   s.index,
    53  	}
    54  }
    55  
    56  // Len returns the count of configurations in the Selection.
    57  func (s Selection[T]) Len() int {
    58  	return len(s.entries)
    59  }
    60  
    61  // Update applies the given entryUpdater to all entries currently in the
    62  // Selection.
    63  func (s Selection[T]) Update(ctx context.Context, entryUpdater EntryUpdater[T]) error {
    64  	for _, e := range s.entries {
    65  		err := e.Update(ctx, entryUpdater)
    66  		if err != nil {
    67  			if errors.Is(err, ErrSkip) {
    68  				continue
    69  			}
    70  
    71  			return err
    72  		}
    73  	}
    74  
    75  	return nil
    76  }
    77  
    78  // Each calls the given iterator function for each Entry in the Selection.
    79  func (s Selection[T]) Each(iterator func(Entry[T])) {
    80  	for _, e := range s.entries {
    81  		iterator(e)
    82  	}
    83  }
    84  
    85  // Entries returns the Entry items included in the current Selection.
    86  func (s Selection[T]) Entries() []Entry[T] {
    87  	return s.entries
    88  }
    89  
    90  // ErrNoEntries is returned when a Selection has no entries.
    91  var ErrNoEntries = errors.New("no entries in selection")
    92  
    93  // First returns the first Entry in the Selection.
    94  func (s Selection[T]) First() (Entry[T], error) {
    95  	if len(s.entries) == 0 {
    96  		return nil, ErrNoEntries
    97  	}
    98  
    99  	return s.entries[0], nil
   100  }
   101  
   102  // Configurations returns the Configuration items included in the current Selection.
   103  func (s Selection[T]) Configurations() []T {
   104  	return lo.Map(s.entries, func(e Entry[T], _ int) T {
   105  		cfg := e.Configuration()
   106  		return *cfg
   107  	})
   108  }