Migrate casemapMap to xirc
This commit is contained in:
parent
2b7a83b676
commit
ebd101820b
@ -348,7 +348,7 @@ type downstreamConn struct {
|
||||
|
||||
lastBatchRef uint64
|
||||
|
||||
monitored casemapMap[struct{}]
|
||||
monitored xirc.CaseMappingMap[struct{}]
|
||||
}
|
||||
|
||||
func newDownstreamConn(srv *Server, ic ircConn, id uint64) *downstreamConn {
|
||||
@ -362,7 +362,7 @@ func newDownstreamConn(srv *Server, ic ircConn, id uint64) *downstreamConn {
|
||||
nickCM: "*",
|
||||
username: "~u",
|
||||
caps: xirc.NewCapRegistry(),
|
||||
monitored: newCasemapMap[struct{}](xirc.CaseMappingASCII),
|
||||
monitored: xirc.NewCaseMappingMap[struct{}](xirc.CaseMappingASCII),
|
||||
registration: new(downstreamRegistration),
|
||||
}
|
||||
if host, _, err := net.SplitHostPort(remoteAddr); err == nil {
|
||||
@ -2650,17 +2650,17 @@ func (dc *downstreamConn) handleMessageRegistered(ctx context.Context, msg *irc.
|
||||
}
|
||||
uc.updateMonitor()
|
||||
case "C": // clear
|
||||
dc.monitored = newCasemapMap[struct{}](uc.network.casemap)
|
||||
dc.monitored = xirc.NewCaseMappingMap[struct{}](uc.network.casemap)
|
||||
uc.updateMonitor()
|
||||
case "L": // list
|
||||
// TODO: be less lazy and pack the list
|
||||
for _, entry := range dc.monitored.m {
|
||||
dc.monitored.ForEach(func(name string, _ struct{}) {
|
||||
dc.SendMessage(&irc.Message{
|
||||
Prefix: dc.srv.prefix(),
|
||||
Command: irc.RPL_MONLIST,
|
||||
Params: []string{dc.nick, entry.originalKey},
|
||||
Params: []string{dc.nick, name},
|
||||
})
|
||||
}
|
||||
})
|
||||
dc.SendMessage(&irc.Message{
|
||||
Prefix: dc.srv.prefix(),
|
||||
Command: irc.RPL_ENDOFMONLIST,
|
||||
@ -2668,9 +2668,7 @@ func (dc *downstreamConn) handleMessageRegistered(ctx context.Context, msg *irc.
|
||||
})
|
||||
case "S": // status
|
||||
// TODO: be less lazy and pack the lists
|
||||
for _, entry := range dc.monitored.m {
|
||||
target := entry.originalKey
|
||||
|
||||
dc.monitored.ForEach(func(target string, _ struct{}) {
|
||||
cmd := irc.RPL_MONOFFLINE
|
||||
if online := uc.monitored.Get(target); online {
|
||||
cmd = irc.RPL_MONONLINE
|
||||
@ -2685,7 +2683,7 @@ func (dc *downstreamConn) handleMessageRegistered(ctx context.Context, msg *irc.
|
||||
Command: cmd,
|
||||
Params: []string{dc.nick, target},
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
case "CHATHISTORY":
|
||||
var subcommand string
|
||||
|
68
irc.go
68
irc.go
@ -218,74 +218,6 @@ func copyClientTags(tags irc.Tags) irc.Tags {
|
||||
|
||||
var stdCaseMapping = xirc.CaseMappingRFC1459
|
||||
|
||||
type casemapMap[V interface{}] struct {
|
||||
m map[string]casemapEntry[V]
|
||||
casemap xirc.CaseMapping
|
||||
}
|
||||
|
||||
type casemapEntry[V interface{}] struct {
|
||||
originalKey string
|
||||
value V
|
||||
}
|
||||
|
||||
func newCasemapMap[V interface{}](cm xirc.CaseMapping) casemapMap[V] {
|
||||
return casemapMap[V]{
|
||||
m: make(map[string]casemapEntry[V]),
|
||||
casemap: cm,
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *casemapMap[V]) Has(name string) bool {
|
||||
_, ok := cm.m[cm.casemap(name)]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (cm *casemapMap[V]) Len() int {
|
||||
return len(cm.m)
|
||||
}
|
||||
|
||||
func (cm *casemapMap[V]) Get(name string) V {
|
||||
entry, ok := cm.m[cm.casemap(name)]
|
||||
if !ok {
|
||||
var v V
|
||||
return v
|
||||
}
|
||||
return entry.value
|
||||
}
|
||||
|
||||
func (cm *casemapMap[V]) Set(name string, value V) {
|
||||
nameCM := cm.casemap(name)
|
||||
entry, ok := cm.m[nameCM]
|
||||
if !ok {
|
||||
cm.m[nameCM] = casemapEntry[V]{
|
||||
originalKey: name,
|
||||
value: value,
|
||||
}
|
||||
return
|
||||
}
|
||||
entry.value = value
|
||||
cm.m[nameCM] = entry
|
||||
}
|
||||
|
||||
func (cm *casemapMap[V]) Del(name string) {
|
||||
delete(cm.m, cm.casemap(name))
|
||||
}
|
||||
|
||||
func (cm *casemapMap[V]) ForEach(f func(string, V)) {
|
||||
for _, entry := range cm.m {
|
||||
f(entry.originalKey, entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
func (cm *casemapMap[V]) SetCaseMapping(newCasemap xirc.CaseMapping) {
|
||||
cm.casemap = newCasemap
|
||||
m := make(map[string]casemapEntry[V], len(cm.m))
|
||||
for _, entry := range cm.m {
|
||||
m[cm.casemap(entry.originalKey)] = entry
|
||||
}
|
||||
cm.m = m
|
||||
}
|
||||
|
||||
func isWordBoundary(r rune) bool {
|
||||
switch r {
|
||||
case '-', '_', '|': // inspired from weechat.look.highlight_regex
|
||||
|
24
upstream.go
24
upstream.go
@ -89,7 +89,7 @@ type upstreamChannel struct {
|
||||
Status xirc.ChannelStatus
|
||||
modes channelModes
|
||||
creationTime string
|
||||
Members casemapMap[*xirc.MembershipSet]
|
||||
Members xirc.CaseMappingMap[*xirc.MembershipSet]
|
||||
complete bool
|
||||
detachTimer *time.Timer
|
||||
}
|
||||
@ -208,14 +208,14 @@ type upstreamConn struct {
|
||||
realname string
|
||||
hostname string
|
||||
modes userModes
|
||||
channels casemapMap[*upstreamChannel]
|
||||
users casemapMap[*upstreamUser]
|
||||
channels xirc.CaseMappingMap[*upstreamChannel]
|
||||
users xirc.CaseMappingMap[*upstreamUser]
|
||||
caps xirc.CapRegistry
|
||||
batches map[string]upstreamBatch
|
||||
away bool
|
||||
account string
|
||||
nextLabelID uint64
|
||||
monitored casemapMap[bool]
|
||||
monitored xirc.CaseMappingMap[bool]
|
||||
|
||||
saslClient sasl.Client
|
||||
saslStarted bool
|
||||
@ -367,8 +367,8 @@ func connectToUpstream(ctx context.Context, network *network) (*upstreamConn, er
|
||||
conn: *newConn(network.user.srv, newNetIRCConn(netConn), &options),
|
||||
network: network,
|
||||
user: network.user,
|
||||
channels: newCasemapMap[*upstreamChannel](cm),
|
||||
users: newCasemapMap[*upstreamUser](cm),
|
||||
channels: xirc.NewCaseMappingMap[*upstreamChannel](cm),
|
||||
users: xirc.NewCaseMappingMap[*upstreamUser](cm),
|
||||
caps: xirc.NewCapRegistry(),
|
||||
batches: make(map[string]upstreamBatch),
|
||||
serverPrefix: &irc.Prefix{Name: "*"},
|
||||
@ -377,7 +377,7 @@ func connectToUpstream(ctx context.Context, network *network) (*upstreamConn, er
|
||||
availableMemberships: stdMemberships,
|
||||
isupport: make(map[string]*string),
|
||||
pendingCmds: make(map[string][]pendingUpstreamCommand),
|
||||
monitored: newCasemapMap[bool](cm),
|
||||
monitored: xirc.NewCaseMappingMap[bool](cm),
|
||||
hasDesiredNick: true,
|
||||
}
|
||||
return uc, nil
|
||||
@ -1174,7 +1174,7 @@ func (uc *upstreamConn) handleMessage(ctx context.Context, msg *irc.Message) err
|
||||
for _, ch := range strings.Split(channels, ",") {
|
||||
if uc.isOurNick(msg.Prefix.Name) {
|
||||
uc.logger.Printf("joined channel %q", ch)
|
||||
members := newCasemapMap[*xirc.MembershipSet](uc.network.casemap)
|
||||
members := xirc.NewCaseMappingMap[*xirc.MembershipSet](uc.network.casemap)
|
||||
uc.channels.Set(ch, &upstreamChannel{
|
||||
Name: ch,
|
||||
conn: uc,
|
||||
@ -2259,10 +2259,10 @@ func (uc *upstreamConn) updateMonitor() {
|
||||
var addList []string
|
||||
seen := make(map[string]struct{})
|
||||
uc.forEachDownstream(func(dc *downstreamConn) {
|
||||
for _, entry := range dc.monitored.m {
|
||||
targetCM := uc.network.casemap(entry.originalKey)
|
||||
dc.monitored.ForEach(func(target string, _ struct{}) {
|
||||
targetCM := uc.network.casemap(target)
|
||||
if targetCM == serviceNickCM {
|
||||
continue
|
||||
return
|
||||
}
|
||||
if !uc.monitored.Has(targetCM) {
|
||||
if _, ok := add[targetCM]; !ok {
|
||||
@ -2272,7 +2272,7 @@ func (uc *upstreamConn) updateMonitor() {
|
||||
} else {
|
||||
seen[targetCM] = struct{}{}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
wantNick := database.GetNick(&uc.user.User, &uc.network.Network)
|
||||
|
12
user.go
12
user.go
@ -93,11 +93,11 @@ type eventUserRun struct {
|
||||
type deliveredClientMap map[string]string // client name -> msg ID
|
||||
|
||||
type deliveredStore struct {
|
||||
m casemapMap[deliveredClientMap]
|
||||
m xirc.CaseMappingMap[deliveredClientMap]
|
||||
}
|
||||
|
||||
func newDeliveredStore(cm xirc.CaseMapping) deliveredStore {
|
||||
return deliveredStore{newCasemapMap[deliveredClientMap](cm)}
|
||||
return deliveredStore{xirc.NewCaseMappingMap[deliveredClientMap](cm)}
|
||||
}
|
||||
|
||||
func (ds deliveredStore) HasTarget(target string) bool {
|
||||
@ -147,9 +147,9 @@ type network struct {
|
||||
stopped chan struct{}
|
||||
|
||||
conn *upstreamConn
|
||||
channels casemapMap[*database.Channel]
|
||||
channels xirc.CaseMappingMap[*database.Channel]
|
||||
delivered deliveredStore
|
||||
pushTargets casemapMap[time.Time]
|
||||
pushTargets xirc.CaseMappingMap[time.Time]
|
||||
lastError error
|
||||
casemap xirc.CaseMapping
|
||||
}
|
||||
@ -161,7 +161,7 @@ func newNetwork(user *user, record *database.Network, channels []database.Channe
|
||||
// don't know which case-mapping will be used by the upstream server yet
|
||||
cm := xirc.CaseMappingNone
|
||||
|
||||
m := newCasemapMap[*database.Channel](cm)
|
||||
m := xirc.NewCaseMappingMap[*database.Channel](cm)
|
||||
for _, ch := range channels {
|
||||
ch := ch
|
||||
m.Set(ch.Name, &ch)
|
||||
@ -174,7 +174,7 @@ func newNetwork(user *user, record *database.Network, channels []database.Channe
|
||||
stopped: make(chan struct{}),
|
||||
channels: m,
|
||||
delivered: newDeliveredStore(cm),
|
||||
pushTargets: newCasemapMap[time.Time](cm),
|
||||
pushTargets: xirc.NewCaseMappingMap[time.Time](cm),
|
||||
casemap: stdCaseMapping,
|
||||
}
|
||||
}
|
||||
|
@ -75,3 +75,71 @@ func ParseCaseMapping(s string) CaseMapping {
|
||||
}
|
||||
return cm
|
||||
}
|
||||
|
||||
type CaseMappingMap[V interface{}] struct {
|
||||
m map[string]caseMappingEntry[V]
|
||||
casemap CaseMapping
|
||||
}
|
||||
|
||||
type caseMappingEntry[V interface{}] struct {
|
||||
originalKey string
|
||||
value V
|
||||
}
|
||||
|
||||
func NewCaseMappingMap[V interface{}](cm CaseMapping) CaseMappingMap[V] {
|
||||
return CaseMappingMap[V]{
|
||||
m: make(map[string]caseMappingEntry[V]),
|
||||
casemap: cm,
|
||||
}
|
||||
}
|
||||
|
||||
func (cmm *CaseMappingMap[V]) Has(name string) bool {
|
||||
_, ok := cmm.m[cmm.casemap(name)]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (cmm *CaseMappingMap[V]) Len() int {
|
||||
return len(cmm.m)
|
||||
}
|
||||
|
||||
func (cmm *CaseMappingMap[V]) Get(name string) V {
|
||||
entry, ok := cmm.m[cmm.casemap(name)]
|
||||
if !ok {
|
||||
var v V
|
||||
return v
|
||||
}
|
||||
return entry.value
|
||||
}
|
||||
|
||||
func (cmm *CaseMappingMap[V]) Set(name string, value V) {
|
||||
nameCM := cmm.casemap(name)
|
||||
entry, ok := cmm.m[nameCM]
|
||||
if !ok {
|
||||
cmm.m[nameCM] = caseMappingEntry[V]{
|
||||
originalKey: name,
|
||||
value: value,
|
||||
}
|
||||
return
|
||||
}
|
||||
entry.value = value
|
||||
cmm.m[nameCM] = entry
|
||||
}
|
||||
|
||||
func (cmm *CaseMappingMap[V]) Del(name string) {
|
||||
delete(cmm.m, cmm.casemap(name))
|
||||
}
|
||||
|
||||
func (cmm *CaseMappingMap[V]) ForEach(f func(string, V)) {
|
||||
for _, entry := range cmm.m {
|
||||
f(entry.originalKey, entry.value)
|
||||
}
|
||||
}
|
||||
|
||||
func (cmm *CaseMappingMap[V]) SetCaseMapping(newCasemap CaseMapping) {
|
||||
cmm.casemap = newCasemap
|
||||
m := make(map[string]caseMappingEntry[V], len(cmm.m))
|
||||
for _, entry := range cmm.m {
|
||||
m[cmm.casemap(entry.originalKey)] = entry
|
||||
}
|
||||
cmm.m = m
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user