Skip to content

Commit

Permalink
Improvements to DelimitedStr
Browse files Browse the repository at this point in the history
  • Loading branch information
tobyink committed Sep 16, 2022
1 parent 8eb887a commit fc6a33d
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- `%Error::TypeTiny::CarpInternal` is now an alias for `%Carp::CarpInternal`.
- Type::Tiny::{Class,Duck,Enum,Role} are now exporters.
- Enum types now export constants for each value.
- `Types::Common::String` now provides a `DelimitedStr` type.

Test Suite Statistics:

Expand Down
23 changes: 18 additions & 5 deletions lib/Types/Common/String.pm
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,9 @@ $meta->add_type(
: quotemeta( $delimiter );

return sub {
my @split = split $q_delimiter, $_[0];
my @split = $ws
? split( $q_delimiter, do { ( my $trimmed = $_[0] ) =~ s{\A\s+|\s+\z}{}g; $trimmed } )
: split( $q_delimiter, $_[0] );
return if @split < $min_parts;
return if defined($max_parts) && ( @split > $max_parts );
!$part_constraint or $part_constraint->all( @split );
Expand All @@ -256,7 +258,9 @@ $meta->add_type(
undef,
sprintf(
'do { my $split = [ split %s, %s ]; %s }',
B::perlstring( $q_delimiter ), $v, join( q{ and }, @cond ),
B::perlstring( $q_delimiter ),
$ws ? sprintf( 'do { ( my $trimmed = %s ) =~ s{\A\s+|\s+\z}{}g; $trimmed }', $v ) : $v,
join( q{ and }, @cond ),
),
);
};
Expand All @@ -281,6 +285,11 @@ $meta->add_type(
},
);

DelimitedStr->coercion->add_type_coercions(
Types::Standard::ArrayRef->of( Types::Standard::Str ),
'join( $", @$_ )',
);

__PACKAGE__->meta->make_immutable;

1;
Expand Down Expand Up @@ -388,12 +397,16 @@ B<< DelimitedStr[",", Int, 1, 3] >> will allow between 1 and 3 integers,
separated by commas. So C<< "1,42,-999" >> will pass the type constraint,
but C<< "Hello,45" >> will fail.
The ws parameter allows optional whitespace surrounding the delimiters.
The ws parameter allows optional whitespace surrounding the delimiters,
as well as optional leading and trailing whitespace.
The type, min, max, and ws paramaters are optional.
This type constraint will automatically have a coercion from
B<< ArrayRef[`type] >> which uses C<< join >>.
Parameterized B<DelimitedStr> type constraints will automatically have a
coercion from B<< ArrayRef[`type] >> which uses C<< join >> to join by the
delimiter. The plain unparameterized type constraint B<DelimitedStr> has
a coercion from B<< ArrayRef[Str] >> which joins the strings using the
list separator C<< $" >> (which is a space by default).
=back
Expand Down
27 changes: 25 additions & 2 deletions t/21-types/DelimitedStr.t
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ ok(!DelimitedStr->deprecated, 'DelimitedStr is not deprecated');
ok(!DelimitedStr->is_anon, 'DelimitedStr is not anonymous');
ok(DelimitedStr->can_be_inlined, 'DelimitedStr can be inlined');
is(exception { DelimitedStr->inline_check(q/$xyz/) }, undef, "Inlining DelimitedStr doesn't throw an exception");
ok(!DelimitedStr->has_coercion, "DelimitedStr doesn't have a coercion");
ok(DelimitedStr->has_coercion, "DelimitedStr has a coercion");
ok(DelimitedStr->is_parameterizable, "DelimitedStr is parameterizable");
is(DelimitedStr->type_default, undef, "DelimitedStr has a type_default");

Expand Down Expand Up @@ -117,6 +117,29 @@ while (@tests) {
}
}

{
local $" = '|';
is(
DelimitedStr->coerce( [ 1..4 ] ),
'1|2|3|4',
'The unparameterized type coerces by joining with $"',
);

$" = ',';
is(
DelimitedStr->coerce( [ 1..4 ] ),
'1,2,3,4',
'... and again',
);

$" = '';
is(
DelimitedStr->coerce( [ 1..4 ] ),
'1234',
'... and again',
);
}

use Types::Standard qw( Int ArrayRef );

# Two or three integers, separated by commas, with optional whitespace
Expand All @@ -128,7 +151,7 @@ is( $SomeInts->display_name, q{DelimitedStr[",",Int,2,3,1]}, "\$SomeInts->displa

should_pass( '1,2,3', $SomeInts );
should_pass( '1, 2, 3', $SomeInts );
should_fail( ' 1,2,3 ', $SomeInts ); # this behaviour might change!
should_pass( ' 1,2,3 ' . "\t\n\t", $SomeInts );
should_fail( '1', $SomeInts );
should_fail( '1,2,3,4', $SomeInts );
should_fail( 'foo,bar,baz', $SomeInts );
Expand Down

0 comments on commit fc6a33d

Please sign in to comment.