File: Enum.pm

package info (click to toggle)
libgraphql-perl 0.54-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 712 kB
  • sloc: perl: 5,094; makefile: 2
file content (171 lines) | stat: -rw-r--r-- 3,824 bytes parent folder | download
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;