-
Notifications
You must be signed in to change notification settings - Fork 3
/
types.go
81 lines (66 loc) · 3.06 KB
/
types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package eggql
// types.go has standard GraphQL types like "ID" as well as custom scalars like "Time"
import (
"fmt"
"math/big"
"time"
"github.com/andrewwphillips/eggql/internal/field"
)
// ID is used when a standard GraphQL ID type is required.
// An ID can be used like any other scalar (Int, etc) as a field type, resolver argument type etc.
// It is typically used for a field that uniquely identifies an object, but it is up to the server
// to guarantee uniqueness. It is stored as a string but can be encoded from an integer or string.
type ID = field.ID
// TagHolder is used to declare a field with name "_" (underscore) in a struct to allow metadata (tags)
// to be attached to a struct. (Metadata can only be attached to fields, so we use an "_" field
// to allow attaching metadata to the parent struct.) This is currently just used to attach a
// comment to Go structs that are used to generate a "description" (in the GraphQL schema) for
// objects, interfaces and unions. See the "Star Wars" tutorial for an example.
// Note: A TagHolder, because it is an empty struct, will not add to the size of the containing
// struct if declared at the start.
type TagHolder struct{}
// Time is a custom scalar for representing a point in time
type Time time.Time
// timeFormat represents how a Time is encoded in a string
const timeFormat = time.RFC3339 // GraphQL spec says that any "Time" ext. scalar type should use this format (ISO-8601)
// UnmarshalEGGQL is called when eggql needs to decode a string to a Time
func (pt *Time) UnmarshalEGGQL(in string) error {
tmp, err := time.Parse(timeFormat, in)
if err != nil {
return fmt.Errorf("%w error in UnmarshalEGGQL for custom scalar Time", err)
}
*pt = Time(tmp) // cast from time.Time to eggql.Time
return nil
}
// MarshalEGGQL encodes a Time object to a string
func (t Time) MarshalEGGQL() (string, error) {
return time.Time(t).Format(timeFormat), nil
}
// Date is a custom scalar for a date (no time of day or timezone)
type Date time.Time
// dateFormat is used for encoding/decoding a Date (as a string)
const dateFormat = "2006-01-02"
// UnmarshalEGGQL is called when eggql needs to decode a string to a Date
func (pd *Date) UnmarshalEGGQL(in string) error {
tmp, err := time.Parse(dateFormat, in)
if err != nil {
return fmt.Errorf("%w error in UnmarshalEGGQL for custom scalar Date", err)
}
*pd = Date(tmp) // cast from time.Time to eggql.Date
return nil
}
// MarshalEGGQL encodes a Date object to a string
func (d Date) MarshalEGGQL() (string, error) {
return time.Time(d).Format(dateFormat), nil
}
// BigInt is a custom scalar for representing a big.Int
// Note that we embed a big.Int so that we can use the standard big.Int methods
type BigInt struct{ big.Int }
// UnmarshalEGGQL is called when eggql needs to decode a string to a BigInt
// Note that MarshalEGGQL is not needed to encode a BigInt (big.Int.String() is used)
func (bi *BigInt) UnmarshalEGGQL(in string) error {
if err := bi.Int.UnmarshalText([]byte(in)); err != nil {
return fmt.Errorf("%w error in UnmarshalEGGQL for custom scalar BigInt", err)
}
return nil
}