func (m *ChannelModes) ApplyDiff(d *ModeDiff) {
	for mode := range d.pos.modes {
		m.setMode(mode)
	}
	for mode, arg := range d.pos.argModes {
		m.setArg(mode, arg)
	}
	for mode, args := range d.pos.addressModes {
		for i := 0; i < len(args); i++ {
			m.setAddress(mode, args[i])
		}
	}
	for mode := range d.neg.modes {
		m.unsetMode(mode)
	}
	for mode, arg := range d.neg.argModes {
		m.unsetArg(mode, arg)
	}
	for mode, args := range d.neg.addressModes {
		for i := 0; i < len(args); i++ {
			m.unsetAddress(mode, args[i])
		}
	}
}
ApplyDiff applies a ModeDiff to the current modeset instance.
package data
import (
	"encoding/json"
	"errors"
	"strings"
	"github.com/aarondl/ultimateq/api"
)
type ChannelModes struct {
	modes        map[rune]bool
	argModes     map[rune]string
	addressModes map[rune][]string
	addresses int
	*modeKinds
}
func NewChannelModes(m *modeKinds) ChannelModes {
	return ChannelModes{
		modes:        make(map[rune]bool),
		argModes:     make(map[rune]string),
		addressModes: make(map[rune][]string),
		modeKinds:    m,
	}
}
func (m *ChannelModes) Clone() ChannelModes {
	cm := ChannelModes{
		modes:        make(map[rune]bool, len(m.modes)),
		argModes:     make(map[rune]string, len(m.argModes)),
		addressModes: make(map[rune][]string, len(m.addressModes)),
		modeKinds:    m.modeKinds,
	}
	for k, v := range m.modes {
		cm.modes[k] = v
	}
	for k, v := range m.argModes {
		cm.argModes[k] = v
	}
	for k, v := range m.addressModes {
		cm.addressModes[k] = v
	}
	return cm
}
type channelModesJSON struct {
	Modes        map[string]bool     `json:"modes"`
	ArgModes     map[string]string   `json:"arg_modes"`
	AddressModes map[string][]string `json:"address_modes"`
	Addresses    int                 `json:"addresses"`
	ModeKinds    *modeKinds          `json:"mode_kinds"`
}
func (c ChannelModes) MarshalJSON() ([]byte, error) {
	var toJSON channelModesJSON
	if c.modes != nil {
		toJSON.Modes = make(map[string]bool, len(c.modes))
		for k, v := range c.modes {
			toJSON.Modes[string(k)] = v
		}
	}
	if c.argModes != nil {
		toJSON.ArgModes = make(map[string]string, len(c.argModes))
		for k, v := range c.argModes {
			toJSON.ArgModes[string(k)] = v
		}
	}
	if c.addressModes != nil {
		toJSON.AddressModes = make(map[string][]string, len(c.addressModes))
		for k, v := range c.addressModes {
			toJSON.AddressModes[string(k)] = append([]string{}, v...)
		}
	}
	toJSON.Addresses = c.addresses
	toJSON.ModeKinds = c.modeKinds
	return json.Marshal(toJSON)
}
func (c *ChannelModes) UnmarshalJSON(b []byte) error {
	var fromJSON channelModesJSON
	if err := json.Unmarshal(b, &fromJSON); err != nil {
		return err
	}
	if fromJSON.Modes != nil {
		c.modes = make(map[rune]bool, len(fromJSON.Modes))
		for k, v := range fromJSON.Modes {
			if len(k) != 1 {
				return errors.New("modes is a map of char to bool")
			}
			c.modes[rune(k[0])] = v
		}
	}
	if fromJSON.ArgModes != nil {
		c.argModes = make(map[rune]string, len(fromJSON.ArgModes))
		for k, v := range fromJSON.ArgModes {
			if len(k) != 1 {
				return errors.New("arg_modes is a map of char to string")
			}
			c.argModes[rune(k[0])] = v
		}
	}
	if fromJSON.AddressModes != nil {
		c.addressModes = make(map[rune][]string, len(fromJSON.AddressModes))
		for k, v := range fromJSON.AddressModes {
			if len(k) != 1 {
				return errors.New("address_modes is a map of char to []string")
			}
			c.addressModes[rune(k[0])] = v
		}
	}
	c.addresses = fromJSON.Addresses
	c.modeKinds = fromJSON.ModeKinds
	return nil
}
func (c ChannelModes) ToProto() *api.ChannelModes {
	var proto api.ChannelModes
	if c.modes != nil {
		proto.Modes = make(map[string]bool, len(c.modes))
		for k, v := range c.modes {
			proto.Modes[string(k)] = v
		}
	}
	if c.argModes != nil {
		proto.ArgModes = make(map[string]string, len(c.argModes))
		for k, v := range c.argModes {
			proto.ArgModes[string(k)] = v
		}
	}
	if c.addressModes != nil {
		proto.AddressModes = make(map[string]*api.ChannelModes_AddressMode, len(c.addressModes))
		for k, v := range c.addressModes {
			addressModes := make([]string, len(v))
			copy(addressModes, v)
			proto.AddressModes[string(k)] = &api.ChannelModes_AddressMode{
				ModeAddresses: addressModes,
			}
		}
	}
	proto.Addresses = int32(c.addresses)
	proto.Kinds = c.modeKinds.ToProto()
	return &proto
}
func (c *ChannelModes) FromProto(proto *api.ChannelModes) error {
	if proto.Modes != nil {
		c.modes = make(map[rune]bool, len(proto.Modes))
		for k, v := range proto.Modes {
			if len(k) != 1 {
				return errors.New("modes is a map of char to bool")
			}
			c.modes[rune(k[0])] = v
		}
	}
	if proto.ArgModes != nil {
		c.argModes = make(map[rune]string, len(proto.ArgModes))
		for k, v := range proto.ArgModes {
			if len(k) != 1 {
				return errors.New("arg_modes is a map of char to string")
			}
			c.argModes[rune(k[0])] = v
		}
	}
	if proto.AddressModes != nil {
		c.addressModes = make(map[rune][]string, len(proto.AddressModes))
		for k, v := range proto.AddressModes {
			if len(k) != 1 {
				return errors.New("address_modes is a map of char to []string")
			}
			modeAddresses := make([]string, len(v.ModeAddresses))
			copy(modeAddresses, v.ModeAddresses)
			c.addressModes[rune(k[0])] = modeAddresses
		}
	}
	c.addresses = int(proto.Addresses)
	if c.modeKinds == nil {
		c.modeKinds = new(modeKinds)
	}
	c.modeKinds.FromProto(proto.Kinds)
	return nil
}
func (m *ChannelModes) Apply(modestring string) ([]userMode, []userMode) {
	return apply(m, modestring)
}