s0rg/decompose

View on GitHub
internal/node/ports.go

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
package node

import (
    "cmp"
    "slices"

    "github.com/s0rg/set"
)

type Ports struct {
    ports map[string][]*Port
    order []string
}

func (ps *Ports) Add(process string, p *Port) {
    if ps.ports == nil {
        ps.ports = make(map[string][]*Port)
    }

    ports, ok := ps.ports[process]

    ps.ports[process] = append(ports, p)

    if !ok {
        ps.order = append(ps.order, process)
        slices.Sort(ps.order)
    }
}

func (ps *Ports) Join(other *Ports) {
    other.Iter(func(process string, ports []*Port) {
        for _, p := range ports {
            ps.Add(process, p)
        }
    })
}

func (ps *Ports) Get(p *Port) (name string, ok bool) {
    for name, pl := range ps.ports {
        for _, l := range pl {
            if l.Equal(p) {
                return name, true
            }
        }
    }

    return
}

func (ps *Ports) Iter(it func(process string, p []*Port)) {
    for _, name := range ps.order {
        it(name, ps.ports[name])
    }
}

func (ps *Ports) Len() (rv int) {
    for _, pl := range ps.ports {
        rv += len(pl)
    }

    return rv
}

func (ps *Ports) Compact() {
    for k, pl := range ps.ports {
        slices.SortFunc(pl, func(a, b *Port) int {
            if a.Kind == b.Kind {
                return cmp.Compare(a.Value, b.Value)
            }

            return cmp.Compare(a.Kind, b.Kind)
        })

        ps.ports[k] = slices.CompactFunc(pl, func(a, b *Port) bool {
            return a.Equal(b)
        })
    }
}

func (ps *Ports) HasAny(label ...string) (yes bool) {
    if len(ps.ports) == 0 {
        return
    }

    s := make(set.Unordered[string])
    set.Load(s, label...)

    for _, ports := range ps.ports {
        for _, p := range ports {
            if s.Has(p.Label()) {
                return true
            }
        }
    }

    return false
}

func (ps *Ports) Has(label ...string) (yes bool) {
    if len(ps.ports) == 0 {
        return
    }

    s := make(set.Unordered[string])
    set.Load(s, label...)

    for _, ports := range ps.ports {
        for _, p := range ports {
            s.Del(p.Label())
        }
    }

    return s.Len() == 0
}