package main import ( "errors" ) type Notifier[TNotification any] struct { bufferSize int Listeners map[string]chan TNotification AllowedKeys map[string]bool } func (n *Notifier[TNotification]) Create(id string) error { if _, exists := n.Listeners[id]; exists { return errors.New("This listener already exists") } if _, exists := n.AllowedKeys[id]; !exists { return errors.New("This key cannot be used to create a listener") } n.Listeners[id] = make(chan TNotification, n.bufferSize) return nil } var ChannelFullErr = errors.New("Channel is full") // Ensures the listener exists before sending func (n *Notifier[TNotification]) SendAndCreate(id string, notification TNotification) error { if _, exists := n.Listeners[id]; !exists { if err := n.Create(id); err != nil { return err } } ch := n.Listeners[id] select { case ch <- notification: return nil default: return ChannelFullErr } } func (n *Notifier[TNotification]) Delete(id string) error { if _, exists := n.Listeners[id]; !exists { return errors.New("This listener does not exists") } delete(n.Listeners, id) return nil } func (n *Notifier[TNotification]) AddKey(id string) { n.AllowedKeys[id] = true } func (n *Notifier[TNotification]) RemoveKey(id string) { delete(n.AllowedKeys, id) } func NewNotifier[TNotification any](bufferSize int) Notifier[TNotification] { return Notifier[TNotification]{ bufferSize: bufferSize, Listeners: make(map[string]chan TNotification), AllowedKeys: make(map[string]bool), } }