refactor: add utils responsible for encoding/decoding cursors

This commit is contained in:
Dawid Wysokiński 2024-02-06 08:11:05 +01:00
parent 7f614877c5
commit b6d55b1741
Signed by: Kichiyaki
GPG Key ID: B5445E357FB8B892
2 changed files with 62 additions and 12 deletions

View File

@ -1,7 +1,10 @@
package domain package domain
import ( import (
"bytes"
"encoding/base64"
"net/url" "net/url"
"strings"
) )
func parseURL(rawURL string) (*url.URL, error) { func parseURL(rawURL string) (*url.URL, error) {
@ -14,3 +17,56 @@ func parseURL(rawURL string) (*url.URL, error) {
return u, nil return u, nil
} }
const (
cursorSeparator = ","
cursorKeyValueSeparator = "="
)
func encodeCursor(m map[string]string) string {
if len(m) == 0 {
return ""
}
n := len(cursorSeparator) * (len(m) - 1)
for k, v := range m {
n += len(k) + len(v) + len(cursorKeyValueSeparator)
}
var b bytes.Buffer
b.Grow(n)
for k, v := range m {
if b.Len() > 0 {
_, _ = b.WriteString(cursorSeparator)
}
_, _ = b.WriteString(k)
_, _ = b.WriteString(cursorKeyValueSeparator)
_, _ = b.WriteString(v)
}
return base64.StdEncoding.EncodeToString(b.Bytes())
}
func decodeCursor(s string) (map[string]string, error) {
decodedBytes, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return nil, ErrInvalidCursor
}
decoded := string(decodedBytes)
kvs := strings.Split(decoded, cursorSeparator)
m := make(map[string]string, len(kvs))
for _, kv := range kvs {
k, v, found := strings.Cut(kv, cursorKeyValueSeparator)
if !found {
return nil, ErrInvalidCursor
}
m[k] = v
}
return m, nil
}

View File

@ -1,10 +1,8 @@
package domain package domain
import ( import (
"encoding/base64"
"fmt" "fmt"
"net/url" "net/url"
"strings"
) )
const ( const (
@ -137,18 +135,12 @@ func decodeVersionCursor(encoded string) (VersionCursor, error) {
return VersionCursor{}, err return VersionCursor{}, err
} }
decodedBytes, err := base64.StdEncoding.DecodeString(encoded) m, err := decodeCursor(encoded)
if err != nil { if err != nil {
return VersionCursor{}, ErrInvalidCursor return VersionCursor{}, err
}
decoded := string(decodedBytes)
code, ok := strings.CutPrefix(decoded, "code=")
if !ok {
return VersionCursor{}, ErrInvalidCursor
} }
vc, err := NewVersionCursor(code) vc, err := NewVersionCursor(m["code"])
if err != nil { if err != nil {
return VersionCursor{}, ErrInvalidCursor return VersionCursor{}, ErrInvalidCursor
} }
@ -169,7 +161,9 @@ func (vc VersionCursor) Encode() string {
return "" return ""
} }
return base64.StdEncoding.EncodeToString([]byte("code=" + vc.code)) return encodeCursor(map[string]string{
"code": vc.code,
})
} }
type ListVersionsParams struct { type ListVersionsParams struct {