refactor: add utils responsible for encoding/decoding cursors
This commit is contained in:
parent
7f614877c5
commit
b6d55b1741
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue