SYNOPSIS

     use Data::Sah::Coerce qw(gen_coercer);
    
     # a utility routine: gen_coercer
     my $c = gen_coercer(
         type               => 'date',
         coerce_to          => 'DateTime',
         # coerce_from      => [qw/str_alami/],   # explicitly enable some rules
         # dont_coerce_from => [qw/str_iso8601/], # explicitly disable some rules
         # return_type      => 'str+val',         # default is 'val'
     );
    
     my $val = $c->(123);          # unchanged, 123
     my $val = $c->(1463307881);   # becomes a DateTime object
     my $val = $c->("2016-05-15"); # becomes a DateTime object
     my $val = $c->("2016foo");    # unchanged, "2016foo"

DESCRIPTION

    This distribution contains a standard set of coercion rules for
    Data::Sah. It is separated from the Data-Sah distribution and can be
    used independently.

    A coercion rule is put in
    Data::Sah::Coerce::$COMPILER::$TARGET_TYPE::$SOURCE_TYPE_AND_EXTRA_DESCRIPTION
    module, for example: Data::Sah::Coerce::perl::date::float_epoch for
    converting date from integer (Unix epoch) or
    Data::Sah::Coerce::perl::date::str_iso8601 for converting date from
    ISO8601 strings like "2016-05-15".

    The module must contain meta subroutine which must return a hashref
    that has the following keys (* marks that the key is required):

      * enable_by_default* => bool

      Whether the rule should be used by default. Some rules might be
      useful in certain situations only and can set this key's value to 0.

      To explicitly enable a disabled-by-default rule, a Sah schema can
      specify an attribute x.coerce_from or x.perl.coerce_from, etc to an
      array of coercion rule names to enable explicitly (e.g.
      ["float_epoch", "str_8601"]. On the other hand, to explicitly disable
      an enabled-by-default rule, one can use the x.dont_coerce_from (or
      x.perl.dont_coerce_from, etc).

      * might_die => bool (default: 0)

      Whether the rule will generate code that might die (e.g. does not
      trap failure in a conversion process). An example of a rule like this
      is coercing from string in the form of "YYYY-MM-DD" to a DateTime
      object. The rule might match any string in the form of
      /\A(\d{4})-(\d{2})-(\d{2})\z/ and feed it to DateTime->new, without
      checking of a valid date, so the latter might die.

      An example of rule that "might not die" is coercing from a
      comma-separated string into array. This process should not die unless
      under extraordinary condition (e.g. out of memory).

      For a rule that might die, the program/library that uses the rule
      module might add an eval block around the expr_coerce code that is
      generated by the rule module.

    The module must also contain coerce subroutine which must generate the
    code for coercion. The subroutine must accept a hash of arguments (*
    indicates required arguments):

      * data_term => str

      * coerce_to => str

      Some Sah types are "abstract" and can be represented using a choice
      of several actual types in the target programming language. For
      example, "date" can be represented in Perl as an integer (Unix epoch
      value), or a DateTime object, or a Time::Moment object.

      Not all target Sah types will need this argument.

    The coerce subroutine must return a hashref with the following keys (*
    indicates required keys):

      * expr_match => str

      Expression in the target language to test whether the data can be
      coerced. For example, in Data::Sah::Coerce::perl::date::float_epoch,
      only integers ranging from 10^8 to 2^31 are converted into date.
      Non-integers or integers outside this range are not coerced.

      * expr_coerce => str

      Expression in the target language to actually convert data to the
      target type.

      * modules => hash

      A list of modules required by the expressions.

    Basically, the coerce subroutine must generates a code that accepts a
    non-undef data and must convert this data to the desired type/format
    under the right condition. The code to match the right condition must
    be put in expr_match and the code to convert data must be put in
    expr_coerce.

    Program/library that uses Data::Sah::Coerce can collect rules from the
    rule modules then compose them into the final code, something like (in
    pseudocode):

     if (data is undef) {
       return undef;
     } elsif (data matches expr-match-from-rule1) {
       return expr-coerce-from-rule1;
     } elsif (data matches expr-match-from-rule2) {
       return expr-coerce-from-rule1;
     ...
     } else {
       # does not match any expr-match
       return original data;
     }

VARIABLES

 $Log_Coercer_Code => bool (default: from ENV or 0)

    If set to true, will log the generated coercer code (currently using
    Log::Any at trace level). To see the log message, e.g. to the screen,
    you can use something like:

     % TRACE=1 perl -MLog::Any::Adapter=Screen -MData::Sah::Coerce=gen_coercer \
         -E'my $c = gen_coercer(...)'

ENVIRONMENT

 LOG_SAH_COERCER_CODE => bool

    Set default for $Log_Coercer_Code.

SEE ALSO

    Data::Sah

    Data::Sah::CoerceJS

