const historyLen = 20
const channelBuffer = 10
+// The error returned when a message is sent to a channel that is already
+// closed.
var ErrChannelClosed = errors.New("channel closed")
// Channel definition, also a Set of User Items
closeOnce sync.Once
}
-// Create new channel and start broadcasting goroutine.
+// NewChannel creates a new channel.
func NewChannel() *Channel {
broadcast := make(chan Message, channelBuffer)
})
}
-// Handle a message, will block until done.
+// HandleMsg reacts to a message, will block until done.
func (ch *Channel) HandleMsg(m Message) {
switch m := m.(type) {
case *CommandMsg:
"sync"
)
+// The error returned when an invalid command is issued.
var ErrInvalidCommand = errors.New("invalid command")
+
+// The error returned when a command is given without an owner.
var ErrNoOwner = errors.New("command without owner")
+
+// The error returned when a command is performed without the necessary number
+// of arguments.
var ErrMissingArg = errors.New("missing argument")
+// CommandHandler is the function signature for command handlers..
type CommandHandler func(*Channel, CommandMsg) error
+// Commands is a registry of available commands.
type Commands struct {
handlers map[string]CommandHandler
help map[string]string
sync.RWMutex
}
+// NewCommands returns a new Commands registry.
func NewCommands() *Commands {
return &Commands{
handlers: map[string]CommandHandler{},
}
}
-// Register command. If help string is empty, it will be hidden from Help().
+// Add will register a command. If help string is empty, it will be hidden from
+// Help().
func (c Commands) Add(command string, help string, handler CommandHandler) {
c.Lock()
defer c.Unlock()
return nil
}
-// Execute command message, assumes IsCommand was checked.
+// Run executes a command message.
func (c Commands) Run(channel *Channel, msg CommandMsg) error {
- if msg.from == nil {
+ if msg.From == nil {
return ErrNoOwner
}
"sync"
)
-var ErrIdTaken error = errors.New("id already taken")
-var ErrItemMissing error = errors.New("item does not exist")
+// The error returned when an added id already exists in the set.
+var ErrIdTaken = errors.New("id already taken")
-// Unique identifier for an item
-type Id string
+// The error returned when a requested item does not exist in the set.
+var ErrItemMissing = errors.New("item does not exist")
-// A prefix for a unique identifier
-type IdPrefix Id
+// Id is a unique identifier for an item.
+type Id string
-// An interface for items to store-able in the set
+// Item is an interface for items to store-able in the set
type Item interface {
Id() Id
}
-// Set with string lookup
+// Set with string lookup.
// TODO: Add trie for efficient prefix lookup?
type Set struct {
lookup map[Id]Item
sync.RWMutex
}
-// Create a new set
+// NewSet creates a new set.
func NewSet() *Set {
return &Set{
lookup: map[Id]Item{},
}
}
-// Remove all items and return the number removed
+// Clear removes all items and returns the number removed.
func (s *Set) Clear() int {
s.Lock()
n := len(s.lookup)
return n
}
-// Size of the set right now
+// Len returns the size of the set right now.
func (s *Set) Len() int {
return len(s.lookup)
}
-// Check if user belongs in this set
+// In checks if an item exists in this set.
func (s *Set) In(item Item) bool {
s.RLock()
_, ok := s.lookup[item.Id()]
return ok
}
-// Get user by name
+// Get returns an item with the given Id.
func (s *Set) Get(id Id) (Item, error) {
s.RLock()
item, ok := s.lookup[id]
return item, nil
}
-// Add user to set if user does not exist already
+// Add item to this set if it does not exist already.
func (s *Set) Add(item Item) error {
s.Lock()
defer s.Unlock()
return nil
}
-// Remove user from set
+// Remove item from this set.
func (s *Set) Remove(item Item) error {
s.Lock()
defer s.Unlock()
return nil
}
-// Loop over every item while holding a read lock and apply fn
+// Each loops over every item while holding a read lock and applies fn to each
+// element.
func (s *Set) Each(fn func(item Item)) {
s.RLock()
for _, item := range s.lookup {
s.RUnlock()
}
-// List users by prefix, case insensitive
+// ListPrefix returns a list of items with a prefix, case insensitive.
func (s *Set) ListPrefix(prefix string) []Item {
r := []Item{}
prefix = strings.ToLower(prefix)