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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
package GraphQL::Type::Enum;
use 5.014;
use strict;
use warnings;
use Moo;
use Types::Standard -all;
use GraphQL::Type::Library -all;
use GraphQL::Debug qw(_debug);
use GraphQL::MaybeTypeCheck;
extends qw(GraphQL::Type);
with qw(
GraphQL::Role::Input
GraphQL::Role::Output
GraphQL::Role::Leaf
GraphQL::Role::Nullable
GraphQL::Role::Named
GraphQL::Role::FieldDeprecation
GraphQL::Role::FieldsEither
);
our $VERSION = '0.02';
use constant DEBUG => $ENV{GRAPHQL_DEBUG};
=head1 NAME
GraphQL::Type::Enum - GraphQL enum type
=head1 SYNOPSIS
use GraphQL::Type::Enum;
my %text2value;
my $type = GraphQL::Type::Enum->new(
name => 'Enum',
values => { value1 => {}, value2 => { value => 'yo' } },
);
=head1 ATTRIBUTES
Has C<name>, C<description> from L<GraphQL::Role::Named>.
=head2 values
Hash-ref mapping value labels to a hash-ref description. Description keys,
all optional:
=over
=item value
Perl value of that item. If not specified, will be the string name of
the value. Integers are often useful.
=item deprecation_reason
Reason if deprecated. If supplied, the hash for that value will also
have a key C<is_deprecated> with a true value.
=item description
Description.
=back
=cut
has values => (
is => 'ro',
isa => Map[
StrNameValid,
Dict[
value => Optional[Any],
deprecation_reason => Optional[Str],
description => Optional[Str],
]
],
required => 1,
);
=head1 METHODS
=head2 is_valid
True if given Perl entity is valid value for this type. Relies on unique
stringification of the value.
=cut
has _name2value => (is => 'lazy', isa => Map[StrNameValid, Any]);
sub _build__name2value {
my ($self) = @_;
my $v = $self->values;
+{ map { ($_ => $v->{$_}{value}) } keys %$v };
}
has _value2name => (is => 'lazy', isa => Map[Str, StrNameValid]);
sub _build__value2name {
my ($self) = @_;
my $n2v = $self->_name2value;
DEBUG and _debug('_build__value2name', $self, $n2v);
+{ reverse %$n2v };
}
method is_valid(Any $item) :ReturnType(Bool) {
DEBUG and _debug('is_valid', $item, $item.'', $self->_value2name);
return 1 if !defined $item;
!!$self->_value2name->{$item};
}
method graphql_to_perl(Maybe[Str | ScalarRef] $item) {
DEBUG and _debug('graphql_to_perl', $item, $self->_name2value);
return undef if !defined $item;
$item = $$$item if ref($item) eq 'REF'; # Handle unquoted enum values
$self->_name2value->{$item} // die "Expected type '@{[$self->to_string]}', found $item.\n";
}
method perl_to_graphql(Any $item) {
DEBUG and _debug('perl_to_graphql', $item, $self->_value2name);
return undef if !defined $item;
$self->_value2name->{$item} // die "Expected a value of type '@{[$self->to_string]}' but received: @{[ref($item)||qq{'$item'}]}.\n";
}
=head2 BUILD
Internal method.
=cut
sub BUILD {
my ($self, $args) = @_;
$self->_fields_deprecation_apply('values');
my $v = $self->values;
for my $name (keys %$v) {
$v->{$name}{value} = $name if !exists $v->{$name}{value}; # undef valid
}
}
method from_ast(
HashRef $name2type,
HashRef $ast_node,
) :ReturnType(InstanceOf[__PACKAGE__]) {
my $values = +{ %{$ast_node->{values}} };
$values = $self->_from_ast_field_deprecate($_, $values) for keys %$values;
$self->new(
$self->_from_ast_named($ast_node),
values => $values,
);
}
has to_doc => (is => 'lazy', isa => Str);
sub _build_to_doc {
my ($self) = @_;
my $v = $self->values;
my @valuelines = map {
(
$self->_description_doc_lines($v->{$_}{description}),
$self->_to_doc_field_deprecate($_, $v->{$_}),
)
} sort keys %$v;
join '', map "$_\n",
$self->_description_doc_lines($self->description),
"enum @{[$self->name]} {",
(map length() ? " $_" : "", @valuelines),
"}";
}
__PACKAGE__->meta->make_immutable();
1;
|