60 lines
1.2 KiB
Go
60 lines
1.2 KiB
Go
package utils
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
const (
|
|
DefaultLimit = 50
|
|
MaxLimit = 200
|
|
)
|
|
|
|
type CursorParams struct {
|
|
CursorTime *time.Time
|
|
CursorID *uuid.UUID
|
|
Limit int32
|
|
}
|
|
|
|
func ParseCursor(cursor string) (*time.Time, *uuid.UUID, error) {
|
|
if cursor == "" {
|
|
return nil, nil, nil
|
|
}
|
|
raw, err := base64.RawURLEncoding.DecodeString(cursor)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("invalid cursor encoding")
|
|
}
|
|
parts := strings.SplitN(string(raw), "|", 2)
|
|
if len(parts) != 2 {
|
|
return nil, nil, fmt.Errorf("invalid cursor format")
|
|
}
|
|
t, err := time.Parse(time.RFC3339Nano, parts[0])
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("invalid cursor time")
|
|
}
|
|
id, err := uuid.Parse(parts[1])
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("invalid cursor id")
|
|
}
|
|
return &t, &id, nil
|
|
}
|
|
|
|
func EncodeCursor(t time.Time, id uuid.UUID) string {
|
|
raw := fmt.Sprintf("%s|%s", t.Format(time.RFC3339Nano), id.String())
|
|
return base64.RawURLEncoding.EncodeToString([]byte(raw))
|
|
}
|
|
|
|
func ClampLimit(limit int) int32 {
|
|
if limit <= 0 {
|
|
return DefaultLimit
|
|
}
|
|
if limit > MaxLimit {
|
|
return MaxLimit
|
|
}
|
|
return int32(limit)
|
|
}
|