Improve trigger 'scope' attribute support (RT#119997)
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Types.pm
index e76db93..754ca60 100644 (file)
@@ -1,5 +1,8 @@
 package SQL::Translator::Types;
 
+use warnings;
+use strict;
+
 =head1 NAME
 
 SQL::Translator::Types - Type checking functions
@@ -8,25 +11,26 @@ SQL::Translator::Types - Type checking functions
 
     package Foo;
     use Moo;
-    use SQL::Translator::Types qw(schema_obj);
+    use SQL::Translator::Types qw(schema_obj enum);
 
     has foo => ( is => 'rw', isa => schema_obj('Trigger') );
+    has bar => ( is => 'rw', isa => enum([qw(baz quux quuz)], {
+        msg => "Invalid value for bar: '%s'", icase => 1,
+    });
 
 =head1 DESCRIPTIONS
 
-This module exports fuctions that return coderefs suitable for L<Moo>
+This module exports functions that return coderefs suitable for L<Moo>
 C<isa> type checks.
 Errors are reported using L<SQL::Translator::Utils/throw>.
 
 =cut
 
-use strictures 1;
-
 use SQL::Translator::Utils qw(throw);
 use Scalar::Util qw(blessed);
 
 use Exporter qw(import);
-our @EXPORT_OK = qw(schema_obj);
+our @EXPORT_OK = qw(schema_obj enum);
 
 =head1 FUNCTIONS
 
@@ -47,4 +51,56 @@ sub schema_obj {
     };
 }
 
+=head2 enum(\@strings, [$msg | \%parameters])
+
+Returns a coderef that checks that the argument is one of the provided
+C<@strings>.
+
+=head3 Parameters
+
+=over
+
+=item msg
+
+L<sprintf|perlfunc/sprintf> string for the error message.
+If no other parameters are needed, this can be provided on its own,
+instead of the C<%parameters> hashref.
+The invalid value is passed as the only argument.
+Defaults to C<Invalid value: '%s'>.
+
+=item icase
+
+If true, folds the values to lower case before checking for equality.
+
+=item allow_undef
+
+If true, allow C<undef> in addition to the specified strings.
+
+=item allow_false
+
+If true, allow any false value in addition to the specified strings.
+
+=back
+
+=cut
+
+sub enum {
+    my ($values, $args) = @_;
+    $args ||= {};
+    $args = { msg => $args } unless ref($args) eq 'HASH';
+    my $icase = !!$args->{icase};
+    my %values = map { ($icase ? lc : $_) => undef } @{$values};
+    my $msg = $args->{msg} || "Invalid value: '%s'";
+    my $extra_test =
+        $args->{allow_undef} ? sub { defined $_[0] } :
+        $args->{allow_false} ? sub { !!$_[0] } : undef;
+
+    return sub {
+        my $val = $icase ? lc $_[0] : $_[0];
+        throw(sprintf($msg, $val))
+            if (!defined($extra_test) || $extra_test->($val))
+                && !exists $values{$val};
+    };
+}
+
 1;