--- /dev/null
+
+## MyApp/Types.pm;
+
+ use MooseX::Declare::Types;
+ use MooseX::Types::Moose qw(Str Int);
+ use MooseX::Types::Structured qw(Dict Optional);
+
+ ## Possible interface for facets, with are a bit like roles for types. This
+ ## just a sketch, doesn't represent a lot of thought.
+ use MooseX::Types::Facets {
+ Str => [qw/ hasMinimumLength hasMaximumLength isWords matchesRegex/ ],
+ };
+
+ subtype FullName {
+ as Str;
+ having hasMinimumLength(2),
+ matchesPattern(
+ strategy=>Regexp,
+ pattern=>qr/
+ ^
+ \w{2,35}
+ \s
+ \w{0,25}
+ \s*
+ \w{2,50}
+ $
+ /x
+ );
+
+ parameter length => (
+ isa=>Int,
+ default=>100
+ );
+
+ parameterizes($p Parameters) {
+ having hasMaximumLength($p->length);
+ }
+ }
+
+ subtype Name {
+
+ parameter total_length => (
+ isa=>Int,
+ default=>60,
+ );
+
+ parameter part_max_lengths => (
+ isa=>Dict[
+ first=>Optional[Int],
+ middle=>Optional[Int],
+ last=>Optional[Int],
+ ],
+ );
+
+ my $Namepart = subtype {
+ as Str;
+ having isWords(maximum_words=>1),
+ hasMinimumLength(2);
+
+ parameter max_length => (
+ isa=>int,
+ default=>20
+ );
+
+ parameterize($p Parameters) {
+ having hasMaximumLength($p->max_length);
+ }
+ }
+
+ parameterize($p Parameters) {
+
+ as Dict[
+ first => $NamePart(
+ max_length=>$p->part_max_lengths->{first},
+ ),
+ middle => Optional[
+ $NamePart(
+ max_length=>$p->part_max_lengths->{middle}
+ ),
+ ],
+ last => $NamePart(
+ max_length=>$p->part_max_lengths->{last},
+ ),
+ ];
+
+ having hasMaximumLength($p->total_length);
+ }
+ }
+
+
+## MyApp/MyClass/Foo.pm
+
+ use MooseX::Declare;
+ use MooseX::Types qw(EmailAddress);
+ use MyApp::Types qw(FullName Name);
+
+ Class Foo {
+
+ with Class::DBIx::Role::Result => (
+ resultset_class => '',
+ fields => {
+ fullname => ...,
+ name => ...,
+ },
+ );
+
+ ## fullname would have a minimum of 2 characters, a maximum of 45 and
+ ## would be composed of a maximum of 3 words separated by whitespace
+
+ has fullname => (
+ is=>'rw',
+ isa=>FullName(length=>45),
+ );
+
+ ## name would be a HashRef with two required keys 'first' and 'last'
+ ## and a single optional key called 'middle'. each key value must be a
+ ## str composed of a single word with a minimum character length of 2
+ ## and maximum lengths of first=>35, middle=>25 and last=>50. Also the
+ ## overall total length.
+
+ has name => (
+ is=>'rw',
+ isa=>Name(
+ total_length=>95,
+ part_max_lengths=>{
+ first=>35,
+ middle=>25,
+ last=>50,
+ },
+ ),
+ );
+
+ method email($recipient Email) {
+ ....
+ }
+ }
+
+
+ use aliased MyApp::MyClass::Foo;
+
+ my $foo = Foo->new(
+ fullname=>'Vanessa Li',
+ name=>{
+ first=>'John',
+ middle=>'James',
+ last=>'Napiorkowski',
+ },
+ );
+
+ my $foo_set = Foo->search( name => sub { $self->search ... });
+
+
+ ## COERCSIONS
+
+
+coercion fixPerson($person Person) {
+ from Tuple($name Str, $age Int) {
+ $person->XXXXX(name=>$name, age=>$age);
+ }
+ from Dict(
+ :$fullname Fullname,
+ :$dob DateTime
+ ) {
+ my $name = "$fullname->{first} $fullname->{last}";
+ my $age = ($dob - DateTime-now)->years;
+ return $person->XXX(name=>$name, age=>$age);
+ }
+}
+
+
+has 'attribute' => (
+ is=>'rw',
+ isa=> Person->coercions(fixPerson, MorePeople),
+);
+
+
+
+subtype myDelegate,
+ as Delegate[Signature];
+
+
+type Signature,
+ as Optional[
+ Int,
+ Pairs[
+ Pair[name=>Int],
+ Pair[key=>Str],
+ ],
+
+
+
+
\ No newline at end of file