deep-hash-struct 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +847 -1
- data/deep-hash-struct.gemspec +1 -1
- data/lib/deep/hash/struct/dashboard/table/row.rb +44 -0
- data/lib/deep/hash/struct/dashboard/table.rb +143 -0
- data/lib/deep/hash/struct/dashboard.rb +48 -0
- data/lib/deep/hash/struct/error.rb +14 -0
- data/lib/deep/hash/struct/pp/dashboard/table/row.rb +48 -0
- data/lib/deep/hash/struct/pp/dashboard/table.rb +62 -0
- data/lib/deep/hash/struct/pp/dashboard.rb +29 -0
- data/lib/deep/hash/struct/pp/wrapper.rb +41 -0
- data/lib/deep/hash/struct/pp.rb +5 -0
- data/lib/deep/hash/struct/version.rb +1 -1
- data/lib/deep/hash/struct/wrapper.rb +588 -0
- data/lib/deep/hash/struct.rb +4 -502
- metadata +14 -4
- data/CODE_OF_CONDUCT.md +0 -74
data/deep-hash-struct.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["haimaki4222@gmail.com"]
|
11
11
|
|
12
12
|
spec.summary = "Convenient hash."
|
13
|
-
spec.description = "
|
13
|
+
spec.description = "We can handle data specialized for table display, storage of values can be handled like Struct corresponding to multiple layers."
|
14
14
|
spec.homepage = "https://github.com/etiopiamokamame/deep-hash-struct"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Deep
|
2
|
+
module Hash
|
3
|
+
module Struct
|
4
|
+
class Dashboard
|
5
|
+
class Table
|
6
|
+
class Row
|
7
|
+
include PP::Dashboard::Table::Row
|
8
|
+
|
9
|
+
attr_accessor :opt,
|
10
|
+
:name,
|
11
|
+
:value
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
self.value = options.delete(:value)
|
15
|
+
self.name = options.delete(:name)
|
16
|
+
self.opt = default_options.merge(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def header?
|
20
|
+
opt[:header]
|
21
|
+
end
|
22
|
+
|
23
|
+
def side?
|
24
|
+
opt[:side]
|
25
|
+
end
|
26
|
+
|
27
|
+
def side_header?
|
28
|
+
header? && side?
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def default_options
|
34
|
+
{
|
35
|
+
header: false,
|
36
|
+
side: false
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require "deep/hash/struct/dashboard/table/row"
|
2
|
+
|
3
|
+
module Deep
|
4
|
+
module Hash
|
5
|
+
module Struct
|
6
|
+
class Dashboard
|
7
|
+
class Table
|
8
|
+
include PP::Dashboard::Table
|
9
|
+
|
10
|
+
attr_accessor :opt,
|
11
|
+
:header,
|
12
|
+
:headers,
|
13
|
+
:side,
|
14
|
+
:sides,
|
15
|
+
:body,
|
16
|
+
:bodies,
|
17
|
+
:rows
|
18
|
+
|
19
|
+
def initialize(options = {})
|
20
|
+
self.opt = default_options.merge(options)
|
21
|
+
self.header = Wrapper.new
|
22
|
+
self.side = Wrapper.new
|
23
|
+
self.body = []
|
24
|
+
self.bodies = []
|
25
|
+
self.rows = []
|
26
|
+
header.side_header = opt[:side_header] if matrix?
|
27
|
+
end
|
28
|
+
|
29
|
+
def matrix?
|
30
|
+
opt[:matrix]
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_header
|
34
|
+
yield header
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_side
|
38
|
+
yield side
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_body
|
42
|
+
yield b = Wrapper.new
|
43
|
+
body << b
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse!
|
47
|
+
raise_check!
|
48
|
+
|
49
|
+
self.headers = header.map.each_with_index do |(k, v), i|
|
50
|
+
Row.new(header: true, side: matrix? && i.zero?, name: v, value: k)
|
51
|
+
end
|
52
|
+
|
53
|
+
self.sides = side.map do |k, v|
|
54
|
+
Row.new(side: true, name: v, value: k)
|
55
|
+
end
|
56
|
+
|
57
|
+
self.bodies = if matrix?
|
58
|
+
merge_body = body.shift
|
59
|
+
body.size.times do
|
60
|
+
bs.merge! body.shift
|
61
|
+
end
|
62
|
+
|
63
|
+
sides.map do |s|
|
64
|
+
rs = []
|
65
|
+
rs << s
|
66
|
+
rs += headers.map do |h|
|
67
|
+
next if h.side_header?
|
68
|
+
v = merge_body.to_h.dig(h.value, s.value)
|
69
|
+
v = v.nil? ? opt[:default] : v
|
70
|
+
Row.new(value: v)
|
71
|
+
end.compact
|
72
|
+
rs
|
73
|
+
end
|
74
|
+
else
|
75
|
+
body.map do |r|
|
76
|
+
headers.map do |h|
|
77
|
+
v = r.to_h.dig(h.value)
|
78
|
+
v = v.nil? ? opt[:default] : v
|
79
|
+
Row.new(value: v)
|
80
|
+
end.compact
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
self.rows << headers
|
85
|
+
self.rows += bodies
|
86
|
+
end
|
87
|
+
|
88
|
+
def each
|
89
|
+
if block_given?
|
90
|
+
rows.each do |r|
|
91
|
+
yield r
|
92
|
+
end
|
93
|
+
else
|
94
|
+
rows.each
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def map
|
99
|
+
if block_given?
|
100
|
+
rows.map do |r|
|
101
|
+
yield r
|
102
|
+
end
|
103
|
+
else
|
104
|
+
rows.map
|
105
|
+
end
|
106
|
+
end
|
107
|
+
alias collect map
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def default_options
|
112
|
+
{
|
113
|
+
matrix: false
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
def raise_check!
|
118
|
+
raise Error::UndefinedHeader if header.blank?
|
119
|
+
raise Error::UndefinedSide if matrix? && side.blank?
|
120
|
+
raise Error::InvalidHeader if header.max_stages >= 2
|
121
|
+
raise Error::InvalidSide if matrix? && side.max_stages >= 2
|
122
|
+
raise Error::UnnecessarySide if !matrix? && side.present?
|
123
|
+
if matrix?
|
124
|
+
body.each do |row|
|
125
|
+
row.keys.each do |r|
|
126
|
+
next if header.keys[1..-1].include?(r) && row[r].keys.map { |c| side.include?(c) }.all?
|
127
|
+
raise Error::HeaderRelated
|
128
|
+
end
|
129
|
+
end
|
130
|
+
else
|
131
|
+
body.each do |row|
|
132
|
+
row.keys.each do |r|
|
133
|
+
next if header.include?(r)
|
134
|
+
raise Error::HeaderRelated
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "deep/hash/struct/dashboard/table"
|
2
|
+
|
3
|
+
module Deep
|
4
|
+
module Hash
|
5
|
+
module Struct
|
6
|
+
class Dashboard
|
7
|
+
include Struct::PP::Dashboard
|
8
|
+
|
9
|
+
attr_accessor :tables
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
self.tables = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_table(options = {})
|
16
|
+
tables << if block_given?
|
17
|
+
yield table = Table.new(options)
|
18
|
+
table.parse!
|
19
|
+
table
|
20
|
+
else
|
21
|
+
Table.new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def each
|
26
|
+
if block_given?
|
27
|
+
tables.each do |table|
|
28
|
+
yield table
|
29
|
+
end
|
30
|
+
else
|
31
|
+
tables.each
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def map
|
36
|
+
if block_given?
|
37
|
+
tables.map do |table|
|
38
|
+
yield table
|
39
|
+
end
|
40
|
+
else
|
41
|
+
tables.map
|
42
|
+
end
|
43
|
+
end
|
44
|
+
alias collect map
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Deep
|
2
|
+
module Hash
|
3
|
+
module Struct
|
4
|
+
module Error
|
5
|
+
class UndefinedHeader < StandardError; end
|
6
|
+
class UndefinedSide < StandardError; end
|
7
|
+
class InvalidHeader < StandardError; end
|
8
|
+
class InvalidSide < StandardError; end
|
9
|
+
class UnnecessarySide < StandardError; end
|
10
|
+
class HeaderRelated < StandardError; end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Deep
|
2
|
+
module Hash
|
3
|
+
module Struct
|
4
|
+
module PP
|
5
|
+
module Dashboard
|
6
|
+
module Table
|
7
|
+
module Row
|
8
|
+
def inspect
|
9
|
+
attributes = []
|
10
|
+
attributes << "name=#{name}" unless name.nil?
|
11
|
+
attributes << "value=#{value}" unless value.nil?
|
12
|
+
attributes = "#{attributes.size.zero? ? '' : ' '}#{attributes.join(' ')}"
|
13
|
+
"#<#{self.class.name.split("::").last}#{attributes}>"
|
14
|
+
end
|
15
|
+
|
16
|
+
def pretty_print(q)
|
17
|
+
q.group(2, "#(#{self.class.name}:#{sprintf("0x%x", object_id)} {", "})") do
|
18
|
+
q.breakable
|
19
|
+
|
20
|
+
q.group(2, ":opt => {", "}") do
|
21
|
+
q.breakable
|
22
|
+
q.seplist(opt) do |k, v|
|
23
|
+
q.text ":#{k} => "
|
24
|
+
q.pp v
|
25
|
+
end
|
26
|
+
q.breakable
|
27
|
+
end
|
28
|
+
|
29
|
+
q.breakable
|
30
|
+
|
31
|
+
q.text ":name => "
|
32
|
+
q.pp name
|
33
|
+
|
34
|
+
q.breakable
|
35
|
+
|
36
|
+
q.text ":value => "
|
37
|
+
q.pp value
|
38
|
+
|
39
|
+
q.breakable
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Deep
|
2
|
+
module Hash
|
3
|
+
module Struct
|
4
|
+
module PP
|
5
|
+
module Dashboard
|
6
|
+
module Table
|
7
|
+
def inspect
|
8
|
+
"#<#{self.class.name.split("::").last} matrix=#{matrix?}>"
|
9
|
+
end
|
10
|
+
|
11
|
+
def pretty_print(q)
|
12
|
+
q.group(2, "#(#{self.class.name}:#{sprintf("0x%x", object_id)} {", "})") do
|
13
|
+
q.breakable
|
14
|
+
|
15
|
+
q.text ":matrix => "
|
16
|
+
q.pp matrix?
|
17
|
+
q.breakable
|
18
|
+
|
19
|
+
unless headers.nil? || headers.size.zero?
|
20
|
+
q.group(2, ":headers => [", "]") do
|
21
|
+
q.breakable
|
22
|
+
q.seplist(headers) do |header|
|
23
|
+
q.pp header
|
24
|
+
end
|
25
|
+
end
|
26
|
+
q.breakable
|
27
|
+
end
|
28
|
+
|
29
|
+
unless sides.nil? || sides.size.zero?
|
30
|
+
q.group(2, ":sides => [", "]") do
|
31
|
+
q.breakable
|
32
|
+
q.seplist(sides) do |side|
|
33
|
+
q.pp side
|
34
|
+
end
|
35
|
+
end
|
36
|
+
q.breakable
|
37
|
+
end
|
38
|
+
|
39
|
+
unless bodies.size.zero?
|
40
|
+
q.group(2, ":bodies => [", "]") do
|
41
|
+
q.breakable
|
42
|
+
q.seplist(bodies) do |body|
|
43
|
+
q.group(2, "[", "]") do
|
44
|
+
q.breakable
|
45
|
+
q.seplist(body) do |row|
|
46
|
+
q.pp row
|
47
|
+
end
|
48
|
+
q.breakable
|
49
|
+
end
|
50
|
+
end
|
51
|
+
q.breakable
|
52
|
+
end
|
53
|
+
q.breakable
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Deep
|
2
|
+
module Hash
|
3
|
+
module Struct
|
4
|
+
module PP
|
5
|
+
module Dashboard
|
6
|
+
def inspect
|
7
|
+
"#<#{self.class.name.split("::").last}>"
|
8
|
+
end
|
9
|
+
|
10
|
+
def pretty_print(q)
|
11
|
+
q.group(2, "#(#{self.class.name}:#{sprintf("0x%x", object_id)} {", "})") do
|
12
|
+
q.breakable
|
13
|
+
|
14
|
+
q.group(2, ":tables => [", "]") do
|
15
|
+
q.breakable
|
16
|
+
q.seplist(tables) do |table|
|
17
|
+
q.pp table
|
18
|
+
end
|
19
|
+
q.breakable
|
20
|
+
end
|
21
|
+
|
22
|
+
q.breakable
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Deep
|
2
|
+
module Hash
|
3
|
+
module Struct
|
4
|
+
module PP
|
5
|
+
module Wrapper
|
6
|
+
def inspect
|
7
|
+
v = blank? ? nil : " #{to_h}"
|
8
|
+
"#<#{self.class.name.split("::").last}#{v}>"
|
9
|
+
end
|
10
|
+
|
11
|
+
def pretty_print(q)
|
12
|
+
q.group(2, "#(#{self.class.name}:#{sprintf("0x%x", object_id)} {", "})") do
|
13
|
+
q.breakable
|
14
|
+
|
15
|
+
q.group(2, "{", "}") do
|
16
|
+
q.breakable
|
17
|
+
pretty_print_cycle(q)
|
18
|
+
end
|
19
|
+
|
20
|
+
q.breakable
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def pretty_print_cycle(q, hash = to_h)
|
25
|
+
q.seplist(hash) do |k, v|
|
26
|
+
q.text ":#{k} =>"
|
27
|
+
if [String, Integer].include?(v.class)
|
28
|
+
q.pp v
|
29
|
+
else
|
30
|
+
q.group(2, "{", "}") do
|
31
|
+
q.breakable
|
32
|
+
pretty_print_cycle(q, v)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|