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