73 lines
1.2 KiB
Go
73 lines
1.2 KiB
Go
package domain
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
func parseURL(rawURL string) (*url.URL, error) {
|
|
u, err := url.ParseRequestURI(rawURL)
|
|
if err != nil {
|
|
return nil, InvalidURLError{
|
|
URL: rawURL,
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|