package Dancer2::Core::Role::Serializer; # ABSTRACT: Role for Serializer engines $Dancer2::Core::Role::Serializer::VERSION = '2.1.0'; use Moo::Role; use Dancer2::Core::Types; use Scalar::Util 'blessed'; with 'Dancer2::Core::Role::Engine'; sub hook_aliases { { before_serializer => 'engine.serializer.before', after_serializer => 'engine.serializer.after', } } sub supported_hooks { values %{ shift->hook_aliases } } sub _build_type {'Serializer'} requires 'serialize'; requires 'deserialize'; has log_cb => ( is => 'ro', isa => CodeRef, default => sub { sub {1} }, ); has content_type => ( is => 'ro', isa => Str, required => 1, writer => 'set_content_type' ); around serialize => sub { my ( $orig, $self, $content, $options ) = @_; blessed $self && $self->execute_hook( 'engine.serializer.before', $content ); $content or return $content; my $data; eval { $data = $self->$orig( $content, $options ); blessed $self and $self->execute_hook( 'engine.serializer.after', $data ); 1; } or do { my $error = $@ || 'Zombie Error'; if ( blessed($self) && $self->config->{strict_utf8} ) { die $error; } blessed $self and $self->log_cb->( core => "Failed to serialize content: $error" ); }; return $data; }; around deserialize => sub { my ( $orig, $self, $content, $options ) = @_; $content && length $content > 0 or return $content; my $data; eval { $data = $self->$orig($content, $options); 1; } or do { my $error = $@ || 'Zombie Error'; $self->log_cb->( core => "Failed to deserialize content: $error" ); }; return $data; }; 1; __END__ =pod =encoding UTF-8 =head1 NAME Dancer2::Core::Role::Serializer - Role for Serializer engines =head1 VERSION version 2.1.0 =head1 DESCRIPTION Any class that consumes this role will be able to be used as a serializer under Dancer2. In order to implement this role, the consumer B implement the methods C and C, and should define the C attribute value. =head1 ATTRIBUTES =head2 content_type The I of the object after being serialized. For example, a JSON serializer would have a I content type defined. =head1 METHODS =head2 serialize($content, [\%options]) The serialize method need to be implemented by the consumer. It receives the serializer class object and a reference to the object to be serialized. Should return the object after being serialized, in the content type defined by the C attribute. A third optional argument is a hash reference of options to the serializer. The serialize method must return bytes and therefore has to handle any encoding. =head2 deserialize($content, [\%options]) The inverse method of C. Receives the serializer class object and a string that should be deserialized. The method should return a reference to the deserialized Perl data structure. A third optional argument is a hash reference of options to the serializer. The deserialize method receives encoded bytes and must therefore handle any decoding required. =head1 CONFIGURATION The B configuration variable tells Dancer2 which engine to use. You can change it either in your config.yml file: #Set JSON engine serializer: "JSON" # Prettify JSON output engines: serializer: JSON: pretty: 1 To know which engines are availables please see L =head1 AUTHOR Dancer Core Developers =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Alexis Sukrieh. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut