documentation

releases
Yanick Champoux 2023-11-14 11:45:06 -05:00
parent 6ad18ac108
commit 29716aa141
7 changed files with 184 additions and 66 deletions

View File

@ -7,9 +7,9 @@ vars:
TARGET_BRANCH: main
tasks:
pretty:
tidy:
cmds:
- git diff-ls --diff-filter=ACMR {{.TARGET_BRANCH}} | grep -e '\.pm$\|\.t$' | xargs -IX perltidy -b X
- git diff-ls --diff-filter=ACMR {{.TARGET_BRANCH}} | grep -e '\.pm$\|\.t$|\.pod$' | xargs -IX perltidy -b X
default:
cmds:

View File

@ -9,18 +9,6 @@ use Moo;
use experimental qw/ signatures /;
=head1 DESCRIPTION
The registry for the different types of data managed by the plugin.
=head1 METHODS
=head2 serialize($type,$data,$extra_data={})
Returns the serialized form of C<$data>.
=cut
sub serialize ( $self, $type, $data, $extra_data = {} ) {
return $self->type($type)->serialize( $data, $extra_data );
}
@ -32,12 +20,6 @@ has types => (
has app => ( is => 'ro', );
=head2 add_type($type, $definition = {})
Adds a data type to the registry.
=cut
sub add_type ( $self, $type, $definition = {} ) {
$self->{types}{$type} = Dancer2::Plugin::JsonApi::Schema->new(
registry => $self,
@ -46,13 +28,6 @@ sub add_type ( $self, $type, $definition = {} ) {
);
}
=head2 type($type)
Returns the type's C<Dancer2::Plugin::JsonApi::Schema>. Throws an
error if the type does not exist.
=cut
sub type ( $self, $type ) {
return $self->types->{$type} //=
Dancer2::Plugin::JsonApi::Schema->new( type => $type );

View File

@ -0,0 +1,23 @@
=head1 DESCRIPTION
The registry for the different types of data managed by the plugin.
=head1 METHODS
=head2 add_type($type, $definition = {})
Adds a data type to the registry.
=head2 type($type)
Returns the type's C<Dancer2::Plugin::JsonApi::Schema>. Throws an
error if the type does not exist.
=cut
=head2 serialize($type,$data,$extra_data={})
Returns the serialized form of C<$data>.
=cut

View File

@ -9,26 +9,13 @@ use List::AllUtils qw/ pairmap pairgrep /;
use Set::Object qw/set/;
=head1 ATTRIBUTES
=head2 type
The JSON:API object type. Required.
=cut
has registry => ( is => 'ro' );
has type => (
required => 1,
is => 'ro',
);
=head2 id
Key to use as a reference to the object. Defaults to C<id>. Can be a string,
or a function that will be passed the original data object.
=cut
has id => (
is => 'ro',
default => 'id'
@ -39,17 +26,8 @@ has top_level_links => ( is => 'ro' );
has top_level_meta => ( is => 'ro' );
has relationships => ( is => 'ro', default => sub { +{} } );
has registry => ( is => 'ro' );
has allowed_attributes => ( is => 'ro' );
=head1 METHODS
=head2 top_level_serialize($data,$extra_data = {})
Serializes C<$data> as a top-level
JSON:API object.
=cut
has before_serialize => ( is => 'ro' );
sub serialize ( $self, $data, $extra_data = {} ) {
@ -84,12 +62,6 @@ sub dedupe_included {
return grep { not $seen{ $_->{type} }{ $_->{id} }++ } @_;
}
=head2 serialize_data($data,$extra_data)
Serializes the inner C<$data>.
=cut
has attributes => (
is => 'ro',
default => sub {
@ -104,8 +76,6 @@ has attributes => (
}
);
has before_serialize => ( is => 'ro' );
sub serialize_data ( $self, $data, $extra_data = {}, $included = undef ) {
return [ map { $self->serialize_data( $_, $extra_data, $included ) }

View File

@ -0,0 +1,64 @@
=head1 DESCRIPTION
Defines a type of object to serialize/deserialize from/to the
JSON:API format.
=head1 ATTRIBUTES
=head2 registry
L<Dancer2::Plugin::JsonApi::Registry> to use to find the definition of
other object types.
=head2 before_serialize
Accepts a function, which will be called on the original C<$data> to serialize
to groom it.
before_serialize => sub($data,$xtra) {
# lowercase all keys
return +{ pairmap { lc($a) => $b } %$data }
}
=head2 type
The JSON:API object type. Read-only, required.
=head2 id
Key to use as a reference to the object. Can be a string,
or a function that will be passed the original data object.
Read-only, defaults to the string C<id>.
=head2 links
Links to include as part of the object.
=head2 top_level_links
Links to include to the serialized top level, if the top level object
is of the type defined by this class.
=head2 top_level_meta
Meta information to include to the serialized top level, if the top level object
is of the type defined by this class.
=head2 relationships
Relationships for the object type.
=head2 allowed_attributes
List of attributes that can be serialized/deserialized.
=head1 METHODS
=head2 top_level_serialize($data,$extra_data = {})
Serializes C<$data> as a top-level JSON:API object.
=head2 serialize_data($data,$extra_data)
Serializes the inner C<$data>.

View File

@ -1,5 +1,53 @@
use 5.38.0;
=head1 DESCRIPTION
Serializer for JSON:API. Takes in a data structure, munge it to conforms to the JSON:API format (potentially based on a provided registry of JSON:API schemas),
and encode it as JSON.
Note that using Dancer2::Plugin::JsonApi in an app will automatically
set C<Dancer2::Serializer::JsonApi> as its serializer if it's not already defined.
=head1 SYNOPSIS
As part of a Dancer2 App:
# in config.yaml
serializer: JsonApi
As a standalone module:
use Dancer2::Serializer::JsonApi;
use Dancer2::Plugin::JsonApi::Registry;
my $registry = Dancer2::Plugin::JsonApi::Registry->new;
$registry->add_type( 'spaceship' => {
relationships => {
crew => { type => 'person' }
}
} );
$registry->add_type( 'person' );
my $serializer = Dancer2::Serializer::JsonApi->new(
registry => $registry
);
my $serialized = $serializer->serialize([
'spaceship', {
id => 1,
name => 'Unrequited Retribution',
crew => [
{ id => 2, name => 'One-eye Flanagan', species => 'human' },
{ id => 3, name => 'Flabgor', species => 'Moisterian' },
]
}
]);
=cut
package Dancer2::Serializer::JsonApi;
use Dancer2::Plugin::JsonApi::Registry;
@ -7,20 +55,49 @@ use Dancer2::Serializer::JSON;
use Moo;
=head1 ATTRIBUTES
=head2 content_type
Returns the content type used by the serializer, which is C<application/vnd.api+json>;
=cut
has content_type => ( is => 'ro', default => 'application/vnd.api+json' );
with 'Dancer2::Core::Role::Serializer';
=head2 registry
The L<Dancer2::Plugin::JsonApi::Registry> to use.
=cut
has registry => (
is => 'rw',
default => sub { Dancer2::Plugin::JsonApi::Registry->new }
);
=head2 json_serializer
The underlying JSON serializer. Defaults to L<Dancer2::Serializer::JSON>.
=cut
has json_serializer => (
is => 'ro',
default => sub { Dancer2::Serializer::JSON->new }
);
=head1 METHODS
=head2 $self->serialize( [ $type, $data, $xtra ])
Serializes the C<$data> using the C<$type> from the registry.
The returned value will be a JSON string.
=cut
sub serialize {
my ( $self, $data ) = @_;
@ -28,6 +105,14 @@ sub serialize {
$self->registry->serialize(@$data) );
}
=head2 $self->deserialize( $json_string )
Takes in the serialized C<$json_string> and recreate data out of it.
UNIMPLENTED
=cut
sub deserialize { ... }
1;

View File

@ -1,3 +1,6 @@
# verifies that at least one test file has been modified
# (the goal being that one test has been added or altered)
use 5.38.0;
use Test2::V0;
@ -10,13 +13,11 @@ my $git = Git::Wrapper->new('.');
my $on_target = grep { "* $target_branch" eq $_ } $git->branch;
if ($on_target) {
pass "nothing to check here";
}
else {
my @diff = $git->diff($target_branch);
ok test_file_modified(@diff), "added to a test file";
}
skip_all "already on target branch" if $on_target;
skip_all "manually disabled" if $ENV{NO_NEW_TEST};
ok test_file_modified( $git->diff($target_branch) ), "added to a test file";
sub test_file_modified (@diff) {
my $in_test_file = 0;