From 1d358dfe62e09d96ab92ad6c2ffa0e7a5bb331d7 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 6 Oct 2020 11:49:42 -0400 Subject: [PATCH] model: import from gql.sr.ht --- model/cursor.go | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ model/filter.go | 6 +++++ 2 files changed, 75 insertions(+) create mode 100644 model/cursor.go create mode 100644 model/filter.go diff --git a/model/cursor.go b/model/cursor.go new file mode 100644 index 0000000000000000000000000000000000000000..a49f1d9a945fa7dbb9efec31cd2e6f0a6ac22d5f --- /dev/null +++ b/model/cursor.go @@ -0,0 +1,69 @@ +package model + +import ( + "encoding/json" + "fmt" + "io" + + "git.sr.ht/~sircmpwn/gql.sr.ht/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.Decrypt([]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: "", + } +} diff --git a/model/filter.go b/model/filter.go new file mode 100644 index 0000000000000000000000000000000000000000..52663d693eaf8a74cba54e0f55590a8896d2e1a0 --- /dev/null +++ b/model/filter.go @@ -0,0 +1,6 @@ +package model + +type Filter struct { + Count *int `json:"count"` + Search *string `json:"search"` +}