Skip to content

Instantly share code, notes, and snippets.

@nicolasparada
Created July 26, 2023 19:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicolasparada/a61e02a1a143514ac373acbb82438d96 to your computer and use it in GitHub Desktop.
Save nicolasparada/a61e02a1a143514ac373acbb82438d96 to your computer and use it in GitHub Desktop.
Cursor Type for Pagination. Implements Text, JSON and GQL Marshalers.
package types
import (
"context"
"fmt"
"io"
"time"
"github.com/btcsuite/btcutil/base58"
"github.com/vmihailenco/msgpack/v5"
)
type Cursor struct {
ID string `msgpack:"i"`
CreatedAt time.Time `msgpack:"v"`
}
func (c *Cursor) UnmarshalText(text []byte) error {
b := base58.Decode(string(text))
if err := msgpack.Unmarshal(b, &c); err != nil {
return fmt.Errorf("msgpack unmarshal cursor: %w", err)
}
return nil
}
func (c Cursor) MarshalText() ([]byte, error) {
b, err := msgpack.Marshal(c)
if err != nil {
return nil, fmt.Errorf("msgpack marshal cursor: %w", err)
}
return []byte(base58.Encode(b)), nil
}
func (c *Cursor) UnmarshalJSON(text []byte) error {
return c.UnmarshalText(text)
}
func (c Cursor) MarshalJSON() ([]byte, error) {
return c.MarshalText()
}
func (c *Cursor) UnmarshalGQL(v any) error {
switch v := v.(type) {
case string:
return c.UnmarshalText([]byte(v))
case []byte:
return c.UnmarshalText(v)
default:
return fmt.Errorf("gql unmarshal cursor: invalid type %T", v)
}
}
func (c Cursor) MarshalGQLContext(_ context.Context, w io.Writer) error {
b, err := c.MarshalText()
if err != nil {
return fmt.Errorf("gql marshal cursor: %w", err)
}
_, err = w.Write(b)
if err != nil {
return fmt.Errorf("gql marshal cursor: write: %w", err)
}
return nil
}
func (c Cursor) String() string {
b, err := c.MarshalText()
if err != nil {
return fmt.Sprintf("<cursor_error=%q>", err)
}
return string(b)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment