Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: In r/demo/users, add ListUsersByPrefix #1708

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions examples/gno.land/p/demo/avlhelpers/avlhelpers.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package avlhelpers

import (
"gno.land/p/demo/avl"
)

// Get a list of keys starting from the given prefix. Limit the
// number of results to maxResults.
func ListKeysByPrefix(tree avl.Tree, prefix string, maxResults int) []string {
end := ""
n := len(prefix)
// To make the end of the search, increment the final character ASCII by one.
for n > 0 {
if ascii := int(prefix[n-1]); ascii < 0xff {
end = prefix[0:n-1] + string(ascii+1)
break
}
jefft0 marked this conversation as resolved.
Show resolved Hide resolved

// The last character is 0xff. Try the previous character.
n--
}

result := []string{}
tree.Iterate(prefix, end, func(key string, value interface{}) bool {
result = append(result, key)
if len(result) >= maxResults {
return true
}
return false
})
return result
}
3 changes: 3 additions & 0 deletions examples/gno.land/p/demo/avlhelpers/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module gno.land/p/demo/avlhelpers

require gno.land/p/demo/avl v0.0.0-latest
94 changes: 94 additions & 0 deletions examples/gno.land/p/demo/avlhelpers/z_0_filetest.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// PKGPATH: gno.land/r/test
package test

import (
"encoding/hex"

"gno.land/p/demo/avl"
"gno.land/p/demo/avlhelpers"
"gno.land/p/demo/ufmt"
)

func init() {
}
jefft0 marked this conversation as resolved.
Show resolved Hide resolved

func main() {
tree := avl.Tree{}

{
// Empty tree.
matches := avlhelpers.ListKeysByPrefix(tree, "", 10)
println(ufmt.Sprintf("# matches: %d", len(matches)))
}

tree.Set("alice", "")
tree.Set("andy", "")
tree.Set("bob", "")

{
// Match only alice.
matches := avlhelpers.ListKeysByPrefix(tree, "al", 10)
println(ufmt.Sprintf("# matches: %d", len(matches)))
println("match: " + matches[0])
}

{
// Match alice and andy.
matches := avlhelpers.ListKeysByPrefix(tree, "a", 10)
println(ufmt.Sprintf("# matches: %d", len(matches)))
println("match: " + matches[0])
println("match: " + matches[1])
}

{
// Match alice and andy limited to 1.
matches := avlhelpers.ListKeysByPrefix(tree, "a", 1)
println(ufmt.Sprintf("# matches: %d", len(matches)))
println("match: " + matches[0])
}

tree = avl.Tree{}
tree.Set("a\xff", "")
tree.Set("a\xff\xff", "")
tree.Set("b", "")
tree.Set("\xff\xff\x00", "")

{
// Match only "a\xff\xff".
matches := avlhelpers.ListKeysByPrefix(tree, "a\xff\xff", 10)
println(ufmt.Sprintf("# matches: %d", len(matches)))
println(ufmt.Sprintf("match: %s", hex.EncodeToString([]byte(matches[0]))))
}

{
// Match "a\xff" and "a\xff\xff".
matches := avlhelpers.ListKeysByPrefix(tree, "a\xff", 10)
println(ufmt.Sprintf("# matches: %d", len(matches)))
println(ufmt.Sprintf("match: %s", hex.EncodeToString([]byte(matches[0]))))
println(ufmt.Sprintf("match: %s", hex.EncodeToString([]byte(matches[1]))))
}

{
// Edge case: Match only "\xff\xff\x00".
matches := avlhelpers.ListKeysByPrefix(tree, "\xff\xff", 10)
println(ufmt.Sprintf("# matches: %d", len(matches)))
println(ufmt.Sprintf("match: %s", hex.EncodeToString([]byte(matches[0]))))
}
}

// Output:
// # matches: 0
// # matches: 1
// match: alice
// # matches: 2
// match: alice
// match: andy
// # matches: 1
// match: alice
// # matches: 1
// match: 61ffff
// # matches: 2
// match: 61ff
// match: 61ffff
// # matches: 1
// match: ffff00
1 change: 1 addition & 0 deletions examples/gno.land/r/demo/users/gno.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ module gno.land/r/demo/users

require (
gno.land/p/demo/avl v0.0.0-latest
gno.land/p/demo/avlhelpers v0.0.0-latest
gno.land/p/demo/users v0.0.0-latest
)
7 changes: 7 additions & 0 deletions examples/gno.land/r/demo/users/users.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strings"

"gno.land/p/demo/avl"
"gno.land/p/demo/avlhelpers"
"gno.land/p/demo/users"
)

Expand Down Expand Up @@ -235,6 +236,12 @@ func GetUserByAddressOrName(input users.AddressOrName) *users.User {
return GetUserByAddress(std.Address(input))
}

// Get a list of user names starting from the given prefix. Limit the
// number of results to maxResults. (This can be used for a name search tool.)
func ListUsersByPrefix(prefix string, maxResults int) []string {
jefft0 marked this conversation as resolved.
Show resolved Hide resolved
return avlhelpers.ListKeysByPrefix(name2User, prefix, maxResults)
}

func Resolve(input users.AddressOrName) std.Address {
name, isName := input.GetName()
if !isName {
Expand Down
49 changes: 49 additions & 0 deletions examples/gno.land/r/demo/users/z_11_filetest.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package main

// SEND: 2000000000ugnot

import (
"strconv"

"gno.land/r/demo/users"
)

func main() {
users.Register("", "gnouser", "my profile")

{
// Normal usage
names := users.ListUsersByPrefix("g", 10)
println("# names: " + strconv.Itoa(len(names)))
println("name: " + names[0])
}

{
// Empty prefix: match all
names := users.ListUsersByPrefix("", 10)
println("# names: " + strconv.Itoa(len(names)))
println("name: " + names[0])
}

{
// The prefix is before "gnouser"
names := users.ListUsersByPrefix("gnouseq", 10)
println("# names: " + strconv.Itoa(len(names)))
}

{
// The prefix is after "gnouser"
names := users.ListUsersByPrefix("go", 10)
println("# names: " + strconv.Itoa(len(names)))
}

// More tests are in p/demo/avlhelpers
}

// Output:
// # names: 1
// name: gnouser
jefft0 marked this conversation as resolved.
Show resolved Hide resolved
// # names: 1
// name: gnouser
// # names: 0
// # names: 0
Loading