Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added experimental JSON Pointer support
- Loading branch information
Showing
9 changed files
with
220 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package Mojo::JSON::Pointer; | ||
use Mojo::Base -base; | ||
|
||
use Mojo::Util 'url_unescape'; | ||
use Scalar::Util 'looks_like_number'; | ||
|
||
sub contains { shift->_pointer(1, @_) } | ||
sub get { shift->_pointer(0, @_) } | ||
|
||
# "Google, even though you've enslaved half the world, | ||
# you're still a damn fine search engine." | ||
sub _pointer { | ||
my ($self, $contains, $data, $pointer) = @_; | ||
|
||
# Parse pointer and walk data structure | ||
return unless $pointer =~ s|^/||; | ||
for my $p (split '/', $pointer) { | ||
$p = url_unescape $p; | ||
utf8::decode $p; | ||
|
||
# Hash | ||
if (ref $data eq 'HASH' && exists $data->{$p}) { $data = $data->{$p} } | ||
|
||
# Array | ||
elsif (ref $data eq 'ARRAY' && looks_like_number($p) && @$data > $p) { | ||
$data = $data->[$p]; | ||
} | ||
|
||
# Nothing | ||
else {return} | ||
} | ||
|
||
return $contains ? 1 : $data; | ||
} | ||
|
||
1; | ||
__END__ | ||
=head1 NAME | ||
Mojo::JSON::Pointer - JSON Pointers | ||
=head1 SYNOPSIS | ||
use Mojo::JSON::Pointer; | ||
my $p = Mojo::JSON::Pointer->new; | ||
say $p->get({foo => [23, 'bar']}, '/foo/1'); | ||
say 'Contains "/foo".' if $p->contains({foo => [23, 'bar']}, '/foo'); | ||
=head1 DESCRIPTION | ||
L<Mojo::JSON::Pointer> implements JSON Pointers as described in | ||
L<http://tools.ietf.org/html/draft-pbryan-zyp-json-pointer-02>. Note that | ||
this module is EXPERIMENTAL and might change without warning! | ||
=head1 METHODS | ||
=head2 C<contains> | ||
my $success = $p->contains($data, '/foo/1'); | ||
Check if data structure contains a value that can be identified with the | ||
given JSON Pointer. | ||
=head2 C<get> | ||
my $value = $p->get($data, '/foo/bar'); | ||
Extract value identified by the given JSON Pointer. | ||
=head1 SEE ALSO | ||
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>. | ||
=cut |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
use Mojo::Base -strict; | ||
|
||
use utf8; | ||
|
||
use Test::More tests => 19; | ||
|
||
# "I've had it with this school, Skinner. | ||
# Low test scores, class after class of ugly, ugly children..." | ||
use_ok 'Mojo::JSON::Pointer'; | ||
|
||
# "contains" (hash) | ||
my $p = Mojo::JSON::Pointer->new; | ||
ok $p->contains({foo => 23}, '/foo'), 'contains "/foo"'; | ||
ok !$p->contains({foo => 23}, '/bar'), 'does not contains "/bar"'; | ||
ok $p->contains({foo => {bar => undef}}, '/foo/bar'), 'contains "/foo/bar"'; | ||
|
||
# "contains" (mixed) | ||
ok $p->contains({foo => [0, 1, 2]}, '/foo/0'), 'contains "/foo/0"'; | ||
ok !$p->contains({foo => [0, 1, 2]}, '/foo/9'), 'does not contain "/foo/9"'; | ||
ok !$p->contains({foo => [0, 1, 2]}, '/foo/bar'), | ||
'does not contain "/foo/bar"'; | ||
ok !$p->contains({foo => [0, 1, 2]}, '/0'), 'does not contain "/0"'; | ||
|
||
# "get" (hash) | ||
is $p->get({foo => 'bar'}, '/foo'), 'bar', '"/foo" is "bar"'; | ||
is $p->get({foo => {bar => 42}}, '/foo/bar'), 42, '"/foo/bar" is "42"'; | ||
is_deeply $p->get({foo => {23 => {baz => 0}}}, '/foo/23'), {baz => 0}, | ||
'"/foo/23" is "{baz => 0}"'; | ||
|
||
# "get" (mixed) | ||
is_deeply $p->get({foo => {bar => [1, 2, 3]}}, '/foo/bar'), [1, 2, 3], | ||
'"/foo/bar" is "[1, 2, 3]"'; | ||
is $p->get({foo => {bar => [0, undef, 3]}}, '/foo/bar/0'), 0, | ||
'"/foo/bar/0" is "0"'; | ||
is $p->get({foo => {bar => [0, undef, 3]}}, '/foo/bar/1'), undef, | ||
'"/foo/bar/1" is "undef"'; | ||
is $p->get({foo => {bar => [0, undef, 3]}}, '/foo/bar/2'), 3, | ||
'"/foo/bar/2" is "3"'; | ||
is $p->get({foo => {bar => [0, undef, 3]}}, '/foo/bar/6'), undef, | ||
'"/foo/bar/6" is "undef"'; | ||
|
||
# "get" (encoded) | ||
is $p->get([{'foob ar' => 'foo'}], '/0/foob%20ar'), 'foo', | ||
'"/0/foob%20ar" is "foo"'; | ||
is $p->get([{'foo/bar' => 'bar'}], '/0/foo%2Fbar'), 'bar', | ||
'"/0/foo%2Fbar" is "bar"'; | ||
is $p->get({'♥' => [0, 1]}, '/%E2%99%A5/0'), 0, '"/%E2%99%A5/0" is "0"'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters