Jasonify

 view release on metacpan or  search on metacpan

lib/Jasonify.pm  view on Meta::CPAN



__PACKAGE__->set(
    # Varify/Encode options
    #name     => '',
    #assign   => undef,
    #list     => undef,
    list_sep => ', ',
    beautify => undef,
);



__PACKAGE__->set(
    # Undefify options
    null  => 'null',
);



__PACKAGE__->set(
    # Booleanify options
    false => 'false',
    true  => 'true',
);



__PACKAGE__->set(
    # Stringify options
    quote  => '"',
    #quote1 => undef,
    quote2 => '"',
    #q1     => undef,
    #q2     => undef,
    #sigils => undef,
    longstr => -1,
    #encode1 => undef,
    encode2 => {
        map( { $_ => sprintf( '\\u%04x', $_ ) }
            0x00 .. 0x1f, 0x7f,    # Control characters (C0)
            0x80 .. 0x9f,          # Control characters (C1)
            0x2028, 0x2029,        # Characters not allowed by Javascript
        ),
        # Special cases
        map( { ord( eval qq!"$_"! ) => $_ } qw( \b \t \n \r \" \\\\ ) ),
        utf  => 16,
        byte => '\\u00%02x',
        wide => '\\u%04x',
    },
    #qpairs  => undef,
    #qquotes => undef,
);



__PACKAGE__->set(
    # Numify options
    infinite  => 'Infinity',
    -infinite => '-Infinity',
    nonnumber => 'NaN',
    #num_sep  => undef,
);



__PACKAGE__->set(
    # Lvalueify options
    lvalue    => '$lvalue',
);



__PACKAGE__->set(
    # Vstringify options
    vformat => '"\\u%0*v4x"',
    vsep    => '\\u',
);


#=option Regexpify options
#
#=over
#
#=item ...
#
#=back
#
#=cut
#
#__PACKAGE__->set(
#    # Regexpify options
#    #quote3  => undef,
#    #q3      => undef,
#    #encode3 => undef,
#);



__PACKAGE__->set(
    # Arrayify options
    array_ref => '[$_]',
);



__PACKAGE__->set(
    # Hashify options
    hash_ref         => '{$_}',
    pair             => '$key : $value',
    keymap           => \&Jasonify::keymap,
    keysort          => \&Datify::keysort,
    keyfilter        => undef,
    keyfilterdefault => 1,
    #keywords         => undef,
);



__PACKAGE__->set(
    # Objectify options

lib/Jasonify.pm  view on Meta::CPAN




# Override Datify::booleanify() for SCALAR refs
sub booleanify {
    my $self = &Datify::self;
    local $_ = shift if @_;
    return $self->undefify unless defined;
    return $self->booleanify($$_) if 'SCALAR' eq ref;
    return $_ ? $Jasonify::Boolean::true : $Jasonify::Boolean::false;
}



# Override Datify::keyify() to appropriately stringify all keys
sub keyify {
    my $self = &Datify::self;
    local $_ = shift if @_;

    my $blessed = Scalar::Util::blessed($_);
    return defined($blessed) && $blessed->isa("Jasonify::Literal")
        ? $_
        : $self->stringify($_);
}

# Override Datify::hashkeyvals to handle Jasonify::_key elements
sub hashkeyvals {
    my $self = shift;
    my $hash = shift;

    return map {
        my $blessed = Scalar::Util::blessed($_);
        if ( defined($blessed) ) {
            Carp::croak("Cannot handle $blessed")
                unless $blessed->isa("Jasonify::_key");
            ( $_->string() => $hash->{ $_->key() } );
        } else {
            ( $_ => $hash->{$_} );
        }
    } $self->hashkeys($hash);
}

# Implement a keymap for unusual numbers
sub keymap {
    my $self = &Datify::self;
    local $_ = shift if @_;

    return $_ unless ( LooksLike::infinity($_) || LooksLike::nan($_) );

    my $rep = LooksLike::representation(
        $_,

        "infinity"  => [ $Jasonify::Number::inf,  Jasonify->get("infinite")  ],
        "-infinity" => [ $Jasonify::Number::ninf, Jasonify->get("-infinite") ],
        "nan"       => [ $Jasonify::Number::nan,  Jasonify->get("nonnumber") ],
    );
    # key     string         sortby
    # ======= ============== ===========
    # "inf",  '"Infinity"',  "Infinity"
    # "-inf", '"-Infinity"', "-Infinity"
    # "nan",  '"NaN"',       "NaN"
    return Jasonify::_key->new( $_, @$rep );
}

sub _objectify_via {
    my $self   = shift;
    my $object = shift;

    if ( my $method_name = shift ) {
        return $object->can($method_name);
    }
    return;
}
sub _objectify_via_tag {
    my $self   = shift;
    my $object = shift;

    my $tag_method = $self->get('tag') && $self->get('tag_method');
    return $self->_objectify_via( $object => $tag_method );
}
sub _objectify_via_json {
    my $self   = shift;
    my $object = shift;

    return $self->_objectify_via( $object => $self->get('json_method') );
}



# Override Datify::objectify() to appropriately stringify objects
sub objectify {
    my $self   = &Datify::self;
    my $object = shift;

    return $self->scalarify($object)
        unless defined( my $class = Scalar::Util::blessed($object) );

    my $object_str = $self->get('object');

    my $data;
    if (0) {
    } elsif ( my $code = $self->_find_handler($class) ) {
        return $self->$code($object);
    } elsif ( my $tag = $self->_objectify_via_tag($object) ) {
        $object_str = $self->get('tag');
        $data = $self->arrayify( $object->$tag('JSON') );
    } elsif ( my $to_json = $self->_objectify_via_json($object) ) {
        $data = $self->scalarify( $object->$to_json() );
    } elsif ( my $method = $self->overloaded($object) ) {
        $data = $self->scalarify( $object->$method() );
    } elsif ( my $attrkeyvals = $object->can('_attrkeyvals') ) {
        # TODO: Look this up via meta-objects and such.
        $data = $self->hashify( $object->$attrkeyvals() );
    } else {
        $data = Scalar::Util::reftype $object;

        $data
            = $data eq 'ARRAY'  ? $self->arrayify(  @$object )
            : $data eq 'CODE'   ? $self->codeify(    $object )
            : $data eq 'FORMAT' ? $self->formatify(  $object )
            : $data eq 'GLOB'   ? $self->globify(    $object )

lib/Jasonify.pm  view on Meta::CPAN

=item I<false> => B<'false'>

=item I<true>  => B<'true'>

How the boolean values are encoded.

=back

=head2 Stringify options

=over

=item I<quote> => B<'"'>

Use double-quoted strings in all cases.

=item I<longstr> => B<-1>

All strings are to be considered long, and encoded accordingly.

=item I<econde2> => { ... }

=over

=item I<[[:cntrl:]]> => sprintf( '\\u00%02x', ord($_) )

=item I<"\x{2028}", "\x{2029}"> => sprintf( '\\u%04x', ord($_) )

=item I<"\b"> => B<'\b'>

=item I<"\t"> => B<'\t'>

=item I<"\n"> => B<'\n'>

=item I<"\r"> => B<'\r'>

=item I<'"'>  => B<'\"'>

=item I<'\\'> => B<'\\\\'>

=item I<byte> => B<'\\u00%02x'>

=item I<utf>  => B<16>

=item I<wide> => B<'\\u%04x'>

=back

Special characters, and how they are encoded.

=back

=head2 Numify options

=over

=item I<infinite>  => B<Infinifty>,

=item I<-infinite> => B<-Infinifty>,

=item I<nonnumber> => B<NaN>,

How to encode the values for infinity, negative infinity, and not-a-number.

=back

=head2 Lvalueify options

=over

=item I<lvalue> => B<'$lvalue'>

Encode C<lvalue>s as simple strings.

=back

=head2 Vstringify options

=over

=item I<vformat> => B<'\\u%0*v4x'>

=item I<vsep>    => B<'\\u'>

Encode vstrings as a series of 4-character hex digits separated by C<'\u'>.

=back

=head2 Arraryify options

=over

=item I<array_ref> => B<'[$_]'>

A reference to an C<ARRAY> is encoded in this manner.

=back

=head2 Hashify options

=over

=item I<hash_ref>         => B<'{$_}'>

A reference to a C<HASH> is encoded in this manner.

=item I<pair>             => B<'$key : $value'>

Pairs are encoded in this manner.

=item I<keysort>          => B<\&Datify::keysort>

The function used to sort entries in a hash.

=item I<keyfilter>        => B<undef>

How to filter items in a C<HASH>.

=item I<keyfilterdefault> => B<1>

How to interpret filtered items in a C<HASH>.



( run in 1.648 second using v1.01-cache-2.11-cpan-39bf76dae61 )