PageRenderTime 24ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Dancer2/Core/Role/Serializer.pm

http://github.com/PerlDancer/Dancer2
Perl | 138 lines | 96 code | 39 blank | 3 comment | 4 complexity | f91167611d40e33e7470afc9a0831c77 MD5 | raw file
  1. package Dancer2::Core::Role::Serializer;
  2. # ABSTRACT: Role for Serializer engines
  3. use Moo::Role;
  4. use Dancer2::Core::Types;
  5. use Scalar::Util 'blessed';
  6. with 'Dancer2::Core::Role::Engine';
  7. sub hook_aliases {
  8. {
  9. before_serializer => 'engine.serializer.before',
  10. after_serializer => 'engine.serializer.after',
  11. }
  12. }
  13. sub supported_hooks { values %{ shift->hook_aliases } }
  14. sub _build_type {'Serializer'}
  15. requires 'serialize';
  16. requires 'deserialize';
  17. has log_cb => (
  18. is => 'ro',
  19. isa => CodeRef,
  20. default => sub { sub {1} },
  21. );
  22. has content_type => (
  23. is => 'ro',
  24. isa => Str,
  25. required => 1,
  26. writer => 'set_content_type'
  27. );
  28. around serialize => sub {
  29. my ( $orig, $self, $content, $options ) = @_;
  30. blessed $self && $self->execute_hook( 'engine.serializer.before', $content );
  31. $content or return $content;
  32. my $data;
  33. eval {
  34. $data = $self->$orig( $content, $options );
  35. blessed $self
  36. and $self->execute_hook( 'engine.serializer.after', $data );
  37. 1;
  38. } or do {
  39. my $error = $@ || 'Zombie Error';
  40. blessed $self
  41. and $self->log_cb->( core => "Failed to serialize content: $error" );
  42. };
  43. return $data;
  44. };
  45. around deserialize => sub {
  46. my ( $orig, $self, $content, $options ) = @_;
  47. $content && length $content > 0
  48. or return $content;
  49. my $data;
  50. eval {
  51. $data = $self->$orig($content, $options);
  52. 1;
  53. } or do {
  54. my $error = $@ || 'Zombie Error';
  55. $self->log_cb->( core => "Failed to deserialize content: $error" );
  56. };
  57. return $data;
  58. };
  59. 1;
  60. __END__
  61. =head1 DESCRIPTION
  62. Any class that consumes this role will be able to be used as a
  63. serializer under Dancer2.
  64. In order to implement this role, the consumer B<must> implement the
  65. methods C<serialize> and C<deserialize>, and should define
  66. the C<content_type> attribute value.
  67. =head1 CONFIGURATION
  68. The B<serializer> configuration variable tells Dancer2 which engine to use.
  69. You can change it either in your config.yml file:
  70. #Set JSON engine
  71. serializer: "JSON"
  72. # Prettify JSON output
  73. engines:
  74. serializer:
  75. JSON:
  76. pretty: 1
  77. To know which engines are availables please see L<Dancer2::Manual/"Serializers">
  78. =head1 METHODS
  79. =attr content_type
  80. The I<content type> of the object after being serialized. For example,
  81. a JSON serializer would have a I<application/json> content type
  82. defined.
  83. =method serialize($content, [\%options])
  84. The serialize method need to be implemented by the consumer. It
  85. receives the serializer class object and a reference to the object to
  86. be serialized. Should return the object after being serialized, in the
  87. content type defined by the C<content_type> attribute.
  88. A third optional argument is a hash reference of options to the
  89. serializer.
  90. The serialize method must return bytes and therefore has to handle any
  91. encoding.
  92. =method deserialize($content, [\%options])
  93. The inverse method of C<serialize>. Receives the serializer class
  94. object and a string that should be deserialized. The method should
  95. return a reference to the deserialized Perl data structure.
  96. A third optional argument is a hash reference of options to the
  97. serializer.
  98. The deserialize method receives encoded bytes and must therefore
  99. handle any decoding required.