Files
genqlient/internal/testutil/types.go
T
Dylan R. Johnston c61d7acaa5 Add "generic" option to the "optional" configuration for handling nullable types (#252)
This is an implementation for #251, it adds a new `"generic"` option for
the `"optional"` configuration, and a companion type
`"optional_generic_type"` which is a fully qualified type with a
placeholder `%` for the generic parameter.

Co-authored-by: Dylan R. Johnston <dylan.johnston@familyzone.com>
Co-authored-by: Ben Kraft <ben@benkraft.org>
2023-05-06 10:40:03 -07:00

110 lines
2.0 KiB
Go

package testutil
import (
"context"
"encoding/json"
"time"
"github.com/Khan/genqlient/graphql"
)
type ID string
type Pokemon struct {
Species string `json:"species"`
Level int `json:"level"`
}
func (p Pokemon) Battle(q Pokemon) bool {
return p.Level > q.Level
}
type MyContext interface {
context.Context
MyMethod()
}
func GetClientFromNowhere() (graphql.Client, error) { return nil, nil }
func GetClientFromContext(ctx context.Context) (graphql.Client, error) { return nil, nil }
func GetClientFromMyContext(ctx MyContext) (graphql.Client, error) { return nil, nil }
const dateFormat = "2006-01-02"
func MarshalDate(t *time.Time) ([]byte, error) {
// nil should never happen but we might as well check. zero-time does
// happen because omitempty doesn't consider it zero; we'd prefer to write
// null than "0001-01-01".
//
// (I mean, we're tests. Who cares! But we may as well try to match what
// prod code would want.)
if t == nil || t.IsZero() {
return []byte("null"), nil
}
return []byte(`"` + t.Format(dateFormat) + `"`), nil
}
func UnmarshalDate(b []byte, t *time.Time) error {
// (modified from time.Time.UnmarshalJSON)
var err error
*t, err = time.Parse(`"`+dateFormat+`"`, string(b))
return err
}
type Option[V any] struct {
value V
ok bool
}
func Some[V any](value V) Option[V] {
return Option[V]{value: value, ok: true}
}
func None[V any]() Option[V] {
return Option[V]{ok: false}
}
func (v Option[V]) Unpack() (V, bool) {
return v.value, v.ok
}
func (v Option[V]) Get(fallback V) V {
if v.ok {
return v.value
}
return fallback
}
func FromPtr[V any](ptr *V) Option[V] {
if ptr == nil {
return None[V]()
}
return Some(*ptr)
}
func (value Option[V]) MarshalJSON() ([]byte, error) {
if value.ok {
return json.Marshal(value.value)
} else {
return json.Marshal((*V)(nil))
}
}
func (value *Option[V]) UnmarshalJSON(data []byte) error {
v := (*V)(nil)
err := json.Unmarshal(data, &v)
if err != nil {
return err
}
if v != nil {
value.value = *v
value.ok = true
}
return nil
}