mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
* improve struct and field comments and incorporate into json schema Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * address review feedback Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
109 lines
2.1 KiB
Go
109 lines
2.1 KiB
Go
package file
|
|
|
|
import (
|
|
"sort"
|
|
|
|
"github.com/gohugoio/hashstructure"
|
|
"github.com/scylladb/go-set/strset"
|
|
)
|
|
|
|
// CoordinateSet provides a unique collection of Coordinates with set operations.
|
|
type CoordinateSet struct {
|
|
set map[Coordinates]struct{}
|
|
}
|
|
|
|
func NewCoordinateSet(coordinates ...Coordinates) (s CoordinateSet) {
|
|
for _, l := range coordinates {
|
|
s.Add(l)
|
|
}
|
|
|
|
return s
|
|
}
|
|
|
|
func (s *CoordinateSet) Add(coordinates ...Coordinates) {
|
|
if s.set == nil {
|
|
s.set = make(map[Coordinates]struct{})
|
|
}
|
|
for _, l := range coordinates {
|
|
s.set[l] = struct{}{}
|
|
}
|
|
}
|
|
|
|
func (s CoordinateSet) Remove(coordinates ...Coordinates) {
|
|
if s.set == nil {
|
|
return
|
|
}
|
|
for _, l := range coordinates {
|
|
delete(s.set, l)
|
|
}
|
|
}
|
|
|
|
func (s CoordinateSet) Contains(l Coordinates) bool {
|
|
if s.set == nil {
|
|
return false
|
|
}
|
|
_, ok := s.set[l]
|
|
return ok
|
|
}
|
|
|
|
func (s CoordinateSet) Paths() []string {
|
|
if s.set == nil {
|
|
return nil
|
|
}
|
|
|
|
paths := strset.New()
|
|
for _, c := range s.ToSlice() {
|
|
paths.Add(c.RealPath)
|
|
}
|
|
pathSlice := paths.List()
|
|
sort.Strings(pathSlice)
|
|
return pathSlice
|
|
}
|
|
|
|
func (s CoordinateSet) ToSlice(sorters ...func(a, b Coordinates) int) []Coordinates {
|
|
coordinates := s.ToUnorderedSlice()
|
|
|
|
var sorted bool
|
|
for _, sorter := range sorters {
|
|
if sorter == nil {
|
|
continue
|
|
}
|
|
sort.Slice(coordinates, func(i, j int) bool {
|
|
return sorter(coordinates[i], coordinates[j]) < 0
|
|
})
|
|
sorted = true
|
|
break
|
|
}
|
|
|
|
if !sorted {
|
|
sort.SliceStable(coordinates, func(i, j int) bool {
|
|
if coordinates[i].FileSystemID == coordinates[j].FileSystemID {
|
|
return coordinates[i].RealPath < coordinates[j].RealPath
|
|
}
|
|
return coordinates[i].FileSystemID < coordinates[j].FileSystemID
|
|
})
|
|
}
|
|
|
|
return coordinates
|
|
}
|
|
|
|
func (s CoordinateSet) ToUnorderedSlice() []Coordinates {
|
|
if s.set == nil {
|
|
return nil
|
|
}
|
|
coordinates := make([]Coordinates, len(s.set))
|
|
idx := 0
|
|
for v := range s.set {
|
|
coordinates[idx] = v
|
|
idx++
|
|
}
|
|
return coordinates
|
|
}
|
|
|
|
func (s CoordinateSet) Hash() (uint64, error) {
|
|
return hashstructure.Hash(s.ToSlice(), &hashstructure.HashOptions{
|
|
ZeroNil: true,
|
|
SlicesAsSets: true,
|
|
})
|
|
}
|