have no rows marker work as expected with columns
[scpubgit/JSON-Tree-Viewer.git] / br.pl
diff --git a/br.pl b/br.pl
index 1181443..08fe3b6 100644 (file)
--- a/br.pl
+++ b/br.pl
@@ -75,11 +75,38 @@ sub structure {
   if ($parts[0] =~ /\+/) {
     ($parts[0], my @extra) = split /\+/, $parts[0];
     my $struct = $self->mangle_structure($self->descend($self->root, @parts));
-    return $struct unless $struct->[0]{show_columns};
     my $first = shift @parts;
     my @rest = map [ $_, $self->mangle_structure(
                      $self->descend($self->root, $_, @parts)
                    )->[0] ], @extra;
+    unless ($struct->[0]{show_columns}) {
+      my @cols = @{ $struct->[0]{columns} };
+      if (@cols == 2) {
+        my ($key_name, $value_name) = @cols;
+        my %name;
+        $name{ $_ }++
+          for map $_->{$key_name},
+              map @$_, $struct->[0]{data}, map $_->[1]{data}, @rest;
+        my %value_by_host = (map {
+          my $host = $_->[0];
+          my $data = $_->[1]{data};
+          ($host, +{
+            map { ($_->{$key_name}, $_->{$value_name}) } @$data,
+          });
+        } [$first, $struct->[0]], @rest);
+        my @hosts = ($first, @extra);
+        return [{
+          columns => ['key', @hosts],
+          show_columns => 1,
+          data => [ map {
+            my $key = $_;
+            +{ key => $key, (map {
+              ($_, $value_by_host{$_}{$key});
+            } @hosts)};
+          } sort keys %name ],
+        }];
+      }
+    }
     my %by_name;
     my %host_cols;
     my %complex_cols;
@@ -177,7 +204,8 @@ sub descend {
   my ($self, $target, @path) = @_;
   return unless $target;
   if (blessed($target) and $target->isa('IO::All::File')) {
-    $target = $self->json->decode(scalar $target->all);
+    my $all = $target->all;
+    $target = $self->json->decode($all);
   }
   return $target unless @path;
   my $step = shift @path;
@@ -191,21 +219,25 @@ sub render_table {
     $data->{show_columns} ? { map +($_ => $_), @{$data->{columns}} } : (),
     @{$data->{data}}
   );
+  my $column_count = scalar @{$data->{columns}};
   [ 200, [ 'Content-type' => 'text/html' ], [
     HTML::Tags::to_html_string(
       <html>, <body>, "\n",
       ($data->{wrapper}||sub{@_})->(
         '', <table>, "\n",
-          @rows
-          ? (map { my $el = $_;
-              '  ', ($el->{key} eq '__error__') ? <tr class="error"> : <tr>,
-                (map {
-                  <td>, $self->render_el($el, $_, $el->{$_}), </td>
-                } @{$data->{columns}}),
-              </tr>, "\n"
-            } @rows)
+          (map { my $el = $_;
+            '  ', ($el->{key} eq '__error__') ? <tr class="error"> : <tr>,
+              (map {
+                <td>, $self->render_el($el, $_, $el->{$_}), </td>
+              } @{$data->{columns}}),
+            </tr>, "\n"
+          } @rows),
+          @{$data->{data}}
+          ? ()
           : (<tr class="no-rows">,
-              <td>, 'No entries in this data structure', </td>,
+              <td colspan="$column_count">,
+                'No entries in this data structure',
+              </td>,
             </tr>),
         '', </table>, "\n",
       ),