=head1 INTRODUCTION
-We'd like to be able to add additional 'hints' when declaring our type
+We'd like to be able to add additional 'facets' when declaring our type
constraints. These hints would form an extention to the core types built into
Moose, such as Str, Object, etc. as well as form the foundation for authors of
Type Constraint extentions to also add these hints. The idea is these hints
cast gracefully, that way hints defined at the application level will work
neatly with those defined at a possible database level.
+=head1 PROPOSED SYNTAX
+
+The following is proposed syntax for the faceted types:
+
+ subtype MyType,
+ is Str,
+ which hasMinLenth(5), hasMaxLength(20),
+ where {};
+
=head1 USE CASES
The following are possible use cases.
in the code block it is not introspecable. A possible syntax to declare a Str
type constraint with a maximum length hint might be:
- my $tc = subtype MaxStr10, as Str[MaxLengthInclusive=>10];
+ my $tc = subtype MaxStr10, as Str, which hasMaxInclusiveLength(10);
-this information might be instrospectable via something like:
+this information might be introspectable via something like:
- $tc->meta->hints->max_length_inclusive; ## returns 10
+ $tc->meta->facets->max_length_inclusive; ## returns 10
=head2 DataTime and coercion possibilities
use MooseX::Types::DateTime qw(DateTime);
subtype USEasternDataTime,
- is DateTime[TimeZone=>'US/Eastern'];
+ is DateTime,
+ which hasTimeZone('US/Eastern');
coerce USEasternDataTime,
- from DateTime[TimeZone=>'Floating'];
+ from DateTime,
+ which hasTimeZone('Floating')
via {$_->timezone('US/Eastern')};
The created subtype USEasternDataTime would only pass if the DateTime object
=head2 Code generation and mapping
-Given a type constraint such as:
-
- subtype MaxStr10, as Str[MaxLengthInclusive=>10];
+Given a type constraint such as:
+
+ subtype ValidName,
+ as Str,
+ which hasMaxInclusiveLength(45), isAlpha(),
That becomes part of a class definition:
package MyApp::Person;
...
- has 'short_name' => (isa=>MaxStr10);
+ has 'name' => (isa=>ValidName, required=>1);
A code generator or interpreter could introspect the metadata on the attribute
'short_name' to create a table like:
CREATE TABLE Person (
- short_name varchar(10)
+ short_name varchar(45)
+ );
+
+Please note how the code generator would need to aggregate meta information from
+both the attribute options as well as it's type constraint, since in this case
+the attribute is required. Here's another, more complicated option.
+
+ package MyApp::Types::StatisticsPeople;
+
+ ## both types are limited to 45 alphabetical characters that define a
+ ## single word (no whitespace before or after), like "John", but not allow
+ ## " John", " John ", "john123", etc.
+
+ subtype FirstName,
+ as Str,
+ which hasMaxInclusiveLength(45), isAlpha(), isWord();
+
+ subtype ValidName,
+ as Str,
+ which hasMaxInclusiveLength(45), isAlpha(), isWord();
+
+ package MyApp::Person;
+
+ use Moose;
+ use MyApp::Types::StatisticsPeople (qw/FirstName LastName/);
+
+ has first_name => (isa=>FirstName, required=>1);
+ has last_name => (isa=>LastName, required=>1);
+
+The above might be generated into sql like so (let's assume a database that
+has schema support, like Postgresql,
+
+ CREATE TABLE StatisticsPeople.FirstName (
+ first_name_id uuid,
+ value varchar(45),
+ PRIMARY KEY('first_name_id')
+ );
+
+ CREATE TABLE StatisticsPeople.LastName (
+ last_name_id uuid,
+ value varchar(45),
+ PRIMARY KEY('last_name_id')
+ );
+
+ CREATE TABLE PersonFirstName (
+ fk_person_id uuid,
+ fk_first_name_id uuid,
+ PRIMARY KEY('fk_person_id', 'fk_first_name_id'),
+ )
+
+ CREATE TABLE Person (
+ person_id uuid,
+ fk_first_name_id uuid,
+ fk_last_name_id uuid,
+ PRIMARY KEY ('person_id')
+ CONSTRAINT 'person_validname'
+ FOREIGN KEY ('fk_last_name_id')
+ REFERENCES 'ValidName' ('valid_name_id'),
);
+ my $person = model('Person')->create({
+ person_first_name => { first_name => {value=>'John'} },
+ ...
+ });
+
+Probably an extreme options, but if we have types with all this meta data, why
+not have it reflect down to the database model?
+
[Addional Code examples to follow]
-=head1 CORE TYPES AND HINT HEIRARCHY
+=head1 CORE TYPES AND FACET HEIRARCHY
The following is an outline of the possible hints associated with core Moose
type constraints. Hints are assumed to be inherited.
Int[
Signed
UnSigned
+ Even
+ Odd
]
- SmallInt
- BigInt
Str[
ASCII*
Printable*
+ isDigits* (That is, a string that is a number like "123")
Word (must be a single 'word')
MaxLength
MinLength
ArrayRef[`a][
MaxElements
MinElements
+ hasDuplicates
+ hasOnlyUnique
]
HashRef[`a][
HasAllKeys
Requires
Does
]
+
+**
+Might like to have some stuff from the Math packages, like to validate if a
+value matches a given function, or is in the domain or range of a function.
\ No newline at end of file