sorare/graphql/payload.go

90 lines
1.8 KiB
Go

package graphql
type Payload[T any, P any] struct {
OutermostLayer ContainerLayer[T, P]
}
func (q *Payload[T, P]) GetValue() T {
if q.OutermostLayer == nil {
var res T
return res
}
layer := q.OutermostLayer
for layer.GetInnerLayer() != nil {
layer = layer.GetInnerLayer()
}
return layer.GetValue()
}
func NewPayload[T any, P any](gqlType string, containerLayers ...string) *Payload[T, P] {
if len(containerLayers) == 0 {
return &Payload[T, P]{
OutermostLayer: NewWrapper[T, P](gqlType),
}
}
var buildLayer func(index int) ContainerLayer[T, P]
buildLayer = func(index int) ContainerLayer[T, P] {
if index == len(containerLayers) {
return NewWrapper[T, P](gqlType)
}
return &NestedLayer[T, P]{
gqlType: containerLayers[index],
InnerLayer: buildLayer(index + 1),
}
}
return &Payload[T, P]{OutermostLayer: buildLayer(0)}
}
type ContainerLayer[T any, P any] interface {
GetInnerLayer() ContainerLayer[T, P]
GetValue() T
GetGraphQLType() string
}
type NestedLayer[T any, P any] struct {
gqlType string `graphql:"-"`
InnerLayer ContainerLayer[T, P]
}
func (nl *NestedLayer[T, P]) GetInnerLayer() ContainerLayer[T, P] {
return nl.InnerLayer
}
func (nl *NestedLayer[T, P]) GetValue() T {
var res T
return res
}
func (nl *NestedLayer[T, P]) GetGraphQLType() string {
return nl.gqlType
}
type Wrapper[T any, P any] struct {
gqlType string `graphql:"-"`
Value T
}
func (w Wrapper[T, P]) GetInnerLayer() ContainerLayer[T, P] {
return nil
}
func (w Wrapper[T, P]) GetValue() T {
return w.Value
}
func (w Wrapper[T, P]) GetGraphQLWrapped() T {
return w.Value
}
func (w Wrapper[T, P]) GetGraphQLType() string {
return w.gqlType
}
func NewWrapper[T any, P any](gqlType string) *Wrapper[T, P] {
return &Wrapper[T, P]{
gqlType: gqlType,
}
}