caps: Move most capability-handling types into the caps package

This commit is contained in:
Daniel Oaks
2017-09-29 17:25:58 +10:00
parent 85bfe3818b
commit 275449e6cc
10 changed files with 259 additions and 138 deletions
+2 -1
View File
@@ -45,6 +45,7 @@ const (
UserhostInNames Capability = "userhost-in-names"
)
func (capability Capability) String() string {
// Name returns the name of the given capability.
func (capability Capability) Name() string {
return string(capability)
}
+115
View File
@@ -0,0 +1,115 @@
// Package caps holds capabilities.
package caps
import (
"sort"
"strings"
"sync"
)
// Set holds a set of enabled capabilities.
type Set struct {
sync.RWMutex
// capabilities holds the capabilities this manager has.
capabilities map[Capability]bool
}
// NewSet returns a new Set, with the given capabilities enabled.
func NewSet(capabs ...Capability) *Set {
newSet := Set{
capabilities: make(map[Capability]bool),
}
newSet.Enable(capabs...)
return &newSet
}
// Enable enables the given capabilities.
func (s *Set) Enable(capabs ...Capability) {
s.Lock()
defer s.Unlock()
for _, capab := range capabs {
s.capabilities[capab] = true
}
}
// Disable disables the given capabilities.
func (s *Set) Disable(capabs ...Capability) {
s.Lock()
defer s.Unlock()
for _, capab := range capabs {
delete(s.capabilities, capab)
}
}
// Add adds the given capabilities to this set.
// this is just a wrapper to allow more clear use.
func (s *Set) Add(capabs ...Capability) {
s.Enable(capabs...)
}
// Remove removes the given capabilities from this set.
// this is just a wrapper to allow more clear use.
func (s *Set) Remove(capabs ...Capability) {
s.Disable(capabs...)
}
// Has returns true if this set has the given capabilities.
func (s *Set) Has(caps ...Capability) bool {
s.RLock()
defer s.RUnlock()
for _, cap := range caps {
if !s.capabilities[cap] {
return false
}
}
return true
}
// List return a list of our enabled capabilities.
func (s *Set) List() []Capability {
s.RLock()
defer s.RUnlock()
var allCaps []Capability
for capab := range s.capabilities {
allCaps = append(allCaps, capab)
}
return allCaps
}
// Count returns how many enabled caps this set has.
func (s *Set) Count() int {
s.RLock()
defer s.RUnlock()
return len(s.capabilities)
}
// String returns all of our enabled capabilities as a string.
func (s *Set) String(version Version, values *Values) string {
s.RLock()
defer s.RUnlock()
var strs sort.StringSlice
for capability := range s.capabilities {
capString := capability.Name()
if version == Cap302 {
val, exists := values.Get(capability)
if exists {
capString += "=" + val
}
}
strs = append(strs, capString)
}
// sort the cap string before we send it out
sort.Sort(strs)
return strings.Join(strs, " ")
}
+42
View File
@@ -0,0 +1,42 @@
package caps
import "sync"
// Values holds capability values.
type Values struct {
sync.RWMutex
// values holds our actual capability values.
values map[Capability]string
}
// NewValues returns a new Values.
func NewValues() *Values {
return &Values{
values: make(map[Capability]string),
}
}
// Set sets the value for the given capability.
func (v *Values) Set(capab Capability, value string) {
v.Lock()
defer v.Unlock()
v.values[capab] = value
}
// Unset removes the value for the given capability, if it exists.
func (v *Values) Unset(capab Capability) {
v.Lock()
defer v.Unlock()
delete(v.values, capab)
}
// Get returns the value of the given capability, and whether one exists.
func (v *Values) Get(capab Capability) (string, bool) {
v.RLock()
defer v.RUnlock()
value, exists := v.values[capab]
return value, exists
}
+11
View File
@@ -0,0 +1,11 @@
package caps
// Version is used to select which max version of CAP the client supports.
type Version uint
const (
// Cap301 refers to the base CAP spec.
Cap301 Version = 301
// Cap302 refers to the IRCv3.2 CAP spec.
Cap302 Version = 302
)