Skip to content

Commit

Permalink
normalize nick case
Browse files Browse the repository at this point in the history
  • Loading branch information
slugalisk committed Mar 29, 2022
1 parent ac722ef commit f157f09
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 30 deletions.
1 change: 1 addition & 0 deletions ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ type Nick struct {
Nick string
TokPos int
TokEnd int
Meta interface{}
}

func (n *Nick) Pos() int {
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ go 1.13
require (
github.com/davecgh/go-spew v1.1.1
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813 // indirect
github.com/petar/GoLLRB v0.0.0-20190514000832-33fb24c13b99
golang.org/x/text v0.3.3
github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9
golang.org/x/text v0.3.7
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813 h1:NgO45/5mBLRVfiXerEFzH6ikcZ7DNRPS639xFg3ENzU=
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/dvyukov/go-fuzz v0.0.0-20220220162807-a217d9bdbece h1:6BGhEtGBmkgr8TKLjMBBMpvM/fK0GHj4prrkK1tYPcA=
github.com/dvyukov/go-fuzz v0.0.0-20220220162807-a217d9bdbece/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/petar/GoLLRB v0.0.0-20190514000832-33fb24c13b99 h1:KcEvVBAvyHkUdFAygKAzwB6LAcZ6LS32WHmRD2VyXMI=
github.com/petar/GoLLRB v0.0.0-20190514000832-33fb24c13b99/go.mod h1:HUpKUBZnpzkdx0kD/+Yfuft+uD3zHGtXF/XJB14TUr4=
github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+Tv1WTxkukpXeMlviSxvL7SRgk=
github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
90 changes: 62 additions & 28 deletions parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,17 @@ func compareRuneSlices(a, b []rune) int {
}

func NewNickIndex(values [][]rune) *NickIndex {
n := &NickIndex{values: llrb.New()}
n := &NickIndex{
values: llrb.New(),
tempItem: &nickIndexItem{},
}

items := make([]llrb.Item, len(values))
for i, v := range values {
items[i] = newNickIndexItem(v)
items[i] = &nickIndexItem{
key: runeSliceToLower(v, nil),
nick: string(v),
}
}
n.values.InsertNoReplaceBulk(items...)

Expand All @@ -106,49 +112,77 @@ func NewNickIndex(values [][]rune) *NickIndex {

type NickIndex struct {
sync.Mutex
values *llrb.LLRB
values *llrb.LLRB
tempItem *nickIndexItem
}

func (n *NickIndex) useTempItem(v []rune) *nickIndexItem {
n.tempItem.key = runeSliceToLower(v, n.tempItem.key)
return n.tempItem
}

func (n *NickIndex) Contains(v []rune) bool {
n.Lock()
defer n.Unlock()

return n.values.Has(nickIndexItem(v))
return n.values.Has(n.useTempItem(v))
}

func (n *NickIndex) Get(v []rune) *nickIndexItem {
n.Lock()
defer n.Unlock()

it, _ := n.values.Get(n.useTempItem(v)).(*nickIndexItem)
return it
}

func (n *NickIndex) Insert(v []rune) {
n.InsertWithMeta(v, nil)
}

func (n *NickIndex) InsertWithMeta(v []rune, m interface{}) {
n.Lock()
defer n.Unlock()

n.values.ReplaceOrInsert(newNickIndexItem(v))
n.values.ReplaceOrInsert(&nickIndexItem{
key: runeSliceToLower(v, nil),
nick: string(v),
meta: m,
})
}

func (n *NickIndex) Remove(v []rune) {
n.Lock()
defer n.Unlock()

n.values.Delete(nickIndexItem(v))
n.values.Delete(n.useTempItem(v))
}

func newNickIndexItem(v []rune) nickIndexItem {
r := make(nickIndexItem, len(v))
for i := 0; i < len(v); i++ {
r[i] = unicode.ToLower(v[i])
func runeSliceToLower(src, dst []rune) []rune {
if cap(dst) < len(src) {
dst = make([]rune, len(src))
}
dst = dst[:len(src)]
for i := 0; i < len(src); i++ {
dst[i] = unicode.ToLower(src[i])
}
return r
return dst
}

type nickIndexItem []rune
type nickIndexItem struct {
key []rune
nick string
meta interface{}
}

func (a nickIndexItem) Less(o llrb.Item) bool {
b := o.(nickIndexItem)
if len(a) != len(b) {
return len(a) > len(b)
func (a *nickIndexItem) Less(o llrb.Item) bool {
b := o.(*nickIndexItem)
if len(a.key) != len(b.key) {
return len(a.key) > len(b.key)
}
for i := 0; i < len(a); i++ {
r := unicode.ToLower(b[i])
if a[i] != r {
return a[i] > r
for i := 0; i < len(a.key); i++ {
if a.key[i] != b.key[i] {
return a.key[i] > b.key[i]
}
}
return false
Expand Down Expand Up @@ -244,10 +278,11 @@ func (p *Parser) parseTag() (t *Tag) {
return
}

func (p *Parser) parseNick() (n *Nick) {
func (p *Parser) parseNick(it *nickIndexItem) (n *Nick) {
n = &Nick{
Nick: string(p.lit),
Nick: it.nick,
TokPos: p.pos,
Meta: it.meta,
}

p.next()
Expand All @@ -261,12 +296,11 @@ func (p *Parser) tryParseAtNick() (n *Nick) {

p.next()

if !p.ctx.Nicks.Contains(p.lit) {
return
if it := p.ctx.Nicks.Get(p.lit); it != nil {
n = p.parseNick(it)
n.TokPos = pos
}

n = p.parseNick()
n.TokPos = pos
return
}

Expand Down Expand Up @@ -335,8 +369,8 @@ func (p *Parser) parseSpan(t SpanType) (s *Span) {
s.Insert(p.parseTag())
} else if p.ctx.Emotes.Contains(p.lit) {
s.Insert(p.parseEmote())
} else if p.ctx.Nicks.Contains(p.lit) {
s.Insert(p.parseNick())
} else if it := p.ctx.Nicks.Get(p.lit); it != nil {
s.Insert(p.parseNick(it))
} else {
p.next()
}
Expand Down
12 changes: 12 additions & 0 deletions parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,18 @@ var parseTests = []parseTest{
TokPos: 0,
TokEnd: 10,
}},
{"incorrectly capitalized username", "@ABEOUS hi", &Span{
Type: SpanMessage,
Nodes: []Node{
&Nick{
Nick: "abeous",
TokPos: 0,
TokEnd: 7,
},
},
TokPos: 0,
TokEnd: 10,
}},
{"username in spoiler", "hi ||@wrxst||", &Span{
Type: SpanMessage,
Nodes: []Node{
Expand Down

0 comments on commit f157f09

Please sign in to comment.