mirror of https://git.sr.ht/~sircmpwn/core-go
70 lines
1.2 KiB
Go
70 lines
1.2 KiB
Go
package model
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
|
|
"git.sr.ht/~sircmpwn/core-go/crypto"
|
|
)
|
|
|
|
// TODO: Add field to prevent cursor reuse across unrelated resources
|
|
type Cursor struct {
|
|
Count int `json:"count"`
|
|
Next string `json:"next"`
|
|
Search string `json:"search"`
|
|
}
|
|
|
|
func (cur *Cursor) UnmarshalGQL(v interface{}) error {
|
|
enc, ok := v.(string)
|
|
if !ok {
|
|
return fmt.Errorf("cursor must be strings")
|
|
}
|
|
plain := crypto.DecryptWithoutExpiration([]byte(enc))
|
|
if plain == nil {
|
|
return fmt.Errorf("Invalid cursor")
|
|
}
|
|
err := json.Unmarshal(plain, cur)
|
|
if err != nil {
|
|
// This is guaranteed to be a programming error
|
|
panic(err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (cur Cursor) MarshalGQL(w io.Writer) {
|
|
data, err := json.Marshal(cur)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
w.Write([]byte("\""))
|
|
w.Write(crypto.Encrypt(data))
|
|
w.Write([]byte("\""))
|
|
}
|
|
|
|
func derefOrInt(i *int, d int) int {
|
|
if i != nil {
|
|
return *i
|
|
}
|
|
return d
|
|
}
|
|
|
|
func NewCursor(filter *Filter) *Cursor {
|
|
if filter != nil {
|
|
count := derefOrInt(filter.Count, 25)
|
|
if count <= 0 {
|
|
count = 25
|
|
}
|
|
return &Cursor{
|
|
Next: "",
|
|
Count: count,
|
|
Search: "", // TODO
|
|
}
|
|
}
|
|
return &Cursor{
|
|
Count: 25,
|
|
Next: "",
|
|
Search: "",
|
|
}
|
|
}
|