File Coverage

blib/lib/Rsync/Config/Renderer.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Rsync::Config::Renderer;
2              
3 1     1   49681 use strict;
  1         2  
  1         38  
4 1     1   6 use warnings;
  1         2  
  1         61  
5              
6             our $VERSION = '0.2';
7              
8             use Exception::Class (
9 0           'Rsync::Config::Renderer::Exception::Invalid::Indent' => {
10             description => 'Invalid value: need a non-negative integer!',
11             alias => 'throw_invalid_indent',
12             },
13             'Rsync::Config::Renderer::Exception::Invalid::IndentChar' => {
14             description => 'Invalid value: need a non-empty string!',
15             alias => 'throw_invalid_indent_char',
16             },
17 1     1   506 );
  0            
18              
19             sub new {
20             my ( $class, %opt ) = @_;
21             my $self;
22              
23             $self = bless { $class->_default_options, %opt }, $class;
24             return $self;
25             }
26              
27             sub indent {
28             my $self = shift;
29              
30             return $self->_default_options('indent') if !ref $self;
31             if (@_) {
32             $self->{indent} = $self->_valid_indent(@_);
33             return $self;
34             }
35             return $self->{indent};
36             }
37              
38             sub indent_char {
39             my $self = shift;
40              
41             return $self->_default_options('indent_char') if !ref $self;
42             if (@_) {
43             $self->{indent_char} = $self->_valid_indent_char(@_);
44             return $self;
45             }
46             return $self->{indent_char};
47             }
48              
49             sub indent_string {
50             my $self = shift;
51             my %opt;
52             for my $opt (qw(indent indent_char)) {
53             my $valid = '_valid_' . $opt;
54             $opt{$opt} =
55             @_ ? $self->$valid(shift)
56             : ref $self ? $self->$opt
57             : $self->_default_options($opt);
58             }
59             return $opt{indent_char} x $opt{indent};
60             }
61              
62             sub render {
63             my $self = shift;
64             my @lines = grep { !ref $_ } @_;
65             my %opt = (
66             prefix => q{},
67             suffix => "\n",
68             map { %{$_} } grep { ref $_ eq 'HASH' } @_,
69             );
70             my @indent_args = ();
71             for my $opt (qw(indent indent_char)) {
72             next if !exists $opt{$opt};
73             push @indent_args, $opt{$opt};
74             }
75             for my $line (@lines) {
76             $line = $self->indent_string(@indent_args)
77             . $opt{prefix}
78             . $line
79             . $opt{suffix};
80             }
81             return wantarray ? @lines : join q{}, @lines;
82             }
83              
84             sub _default_options {
85             my $class = shift;
86             my %defaults = (
87             indent => 0,
88             indent_char => "\t",
89             );
90             return @_ ? $defaults{ shift() } : %defaults;
91             }
92              
93             sub _valid_indent {
94             my ( $class, $indent ) = @_;
95             if ( !defined $indent || $indent !~ /^\d+$/xm ) {
96             throw_invalid_indent;
97             }
98             return $indent;
99             }
100              
101             sub _valid_indent_char {
102             my ( $class, $char ) = @_;
103             if ( !defined $char || !length $char ) {
104             throw_invalid_indent;
105             }
106             return $char;
107             }
108              
109             1;
110              
111             __END__