dense 1.1.0 → 1.1.1
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 +5 -5
- data/CHANGELOG.md +6 -0
- data/Makefile +1 -0
- data/README.md +8 -8
- data/dense.gemspec +2 -2
- data/lib/dense.rb +1 -1
- data/lib/dense/methods.rb +2 -2
- data/lib/dense/parser.rb +62 -7
- data/lib/dense/path.rb +35 -10
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 24371919775ff81e60eb86f0e9bae21a13a4cd4458e14a3584b05b7a16e7937b
|
4
|
+
data.tar.gz: '085c7f5db832b45f4c4f0127ad224d4dfa15402b444b5312274f54ac055825d3'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0f291761cfb4aaa3d6151e788dc9200a361deed8556167cc9a219b96f473a9e3373f822c93b2a6940370d0a3d01ad19c17ec1e4e9dfeef48cca399c3273bf7d
|
7
|
+
data.tar.gz: bd667ecb92422f129e474bd2f37121963f0e618b7166e80f82003462944d2616655034b51f567405c614fbfee2405c32f9dc6b3824e650c5de50f9efdf1cb1d5
|
data/CHANGELOG.md
CHANGED
data/Makefile
CHANGED
@@ -8,6 +8,7 @@ VERSION = \
|
|
8
8
|
|
9
9
|
count_lines:
|
10
10
|
find lib -name "*.rb" | xargs cat | ruby -e "p STDIN.readlines.count { |l| l = l.strip; l[0, 1] != '#' && l != '' }"
|
11
|
+
find spec -name "*.rb" | xargs cat | ruby -e "p STDIN.readlines.count { |l| l = l.strip; l[0, 1] != '#' && l != '' }"
|
11
12
|
cl: count_lines
|
12
13
|
|
13
14
|
gemspec_validate:
|
data/README.md
CHANGED
@@ -117,7 +117,7 @@ When it doesn't find, it raises an instance of `KeyError`:
|
|
117
117
|
```ruby
|
118
118
|
Dense.fetch({}, 'a.0.b')
|
119
119
|
# raises
|
120
|
-
# KeyError:
|
120
|
+
# KeyError: found nothing at "a" ("0.b" remains)
|
121
121
|
```
|
122
122
|
|
123
123
|
It might instead raise an instance of `TypeError` if a non-integer key is requested of an array:
|
@@ -125,7 +125,7 @@ It might instead raise an instance of `TypeError` if a non-integer key is reques
|
|
125
125
|
```ruby
|
126
126
|
Dense.fetch({ 'a' => [] }, 'a.k.b')
|
127
127
|
# raises
|
128
|
-
# TypeError:
|
128
|
+
# TypeError: no key "k" for Array at "a"
|
129
129
|
```
|
130
130
|
|
131
131
|
See KeyError and TypeError below for more details.
|
@@ -207,7 +207,7 @@ r # => 'three'
|
|
207
207
|
|
208
208
|
c = { 'a' => [] }
|
209
209
|
Dense.set(c, 'a.b', 1)
|
210
|
-
# => TypeError:
|
210
|
+
# => TypeError: no key "b" for Array at "a"
|
211
211
|
|
212
212
|
|
213
213
|
c = { 'a' => {} }
|
@@ -217,7 +217,7 @@ r # => 1
|
|
217
217
|
|
218
218
|
c = {}
|
219
219
|
Dense.set(c, 'a.0', 1)
|
220
|
-
# => KeyError:
|
220
|
+
# => KeyError: found nothing at "a" ("0" remains)
|
221
221
|
```
|
222
222
|
|
223
223
|
Setting at multiple places in one go is possible:
|
@@ -282,11 +282,11 @@ r # => 3
|
|
282
282
|
It fails with a `KeyError` or a `TypeError` if it cannot unset.
|
283
283
|
```ruby
|
284
284
|
Dense.unset({}, 'a')
|
285
|
-
# => KeyError:
|
285
|
+
# => KeyError: found nothing at "a"
|
286
286
|
Dense.unset([], 'a')
|
287
|
-
# => TypeError:
|
287
|
+
# => TypeError: no key "a" for Array at root
|
288
288
|
Dense.unset([], '1')
|
289
|
-
# => KeyError:
|
289
|
+
# => KeyError: found nothing at "1"
|
290
290
|
```
|
291
291
|
|
292
292
|
Unsetting multiple values is OK:
|
@@ -309,7 +309,7 @@ e =
|
|
309
309
|
rescue => err
|
310
310
|
err
|
311
311
|
end
|
312
|
-
# => #<KeyError:
|
312
|
+
# => #<KeyError: found nothing at "a" ("b" remains)>
|
313
313
|
e.full_path
|
314
314
|
# => "a"
|
315
315
|
e.miss
|
data/dense.gemspec
CHANGED
@@ -27,9 +27,9 @@ Fetching deep in a dense structure. A kind of bastard of JSONPath.
|
|
27
27
|
"#{s.name}.gemspec",
|
28
28
|
]
|
29
29
|
|
30
|
-
s.add_runtime_dependency 'raabro', '>= 1.1.5'
|
30
|
+
s.add_runtime_dependency 'raabro', '~> 1.1', '>= 1.1.5'
|
31
31
|
|
32
|
-
s.add_development_dependency 'rspec', '~> 3.
|
32
|
+
s.add_development_dependency 'rspec', '~> 3.7'
|
33
33
|
|
34
34
|
s.require_path = 'lib'
|
35
35
|
end
|
data/lib/dense.rb
CHANGED
data/lib/dense/methods.rb
CHANGED
@@ -126,7 +126,7 @@ module Dense; class << self
|
|
126
126
|
path1 = Dense::Path.make(miss[1] + [ miss[3] ]).to_s.inspect
|
127
127
|
path2 = Dense::Path.make(miss[4]).to_s.inspect
|
128
128
|
|
129
|
-
msg = "
|
129
|
+
msg = "found nothing at #{path1}"
|
130
130
|
msg = "#{msg} (#{path2} remains)" if path2 != '""'
|
131
131
|
|
132
132
|
make_error(KeyError, msg, path, miss)
|
@@ -138,7 +138,7 @@ module Dense; class << self
|
|
138
138
|
cla = miss[2].class
|
139
139
|
pat = miss[1].empty? ? 'root' : Dense::Path.make(miss[1]).to_s.inspect
|
140
140
|
|
141
|
-
make_error(TypeError, "
|
141
|
+
make_error(TypeError, "no key #{key} for #{cla} at #{pat}", path, miss)
|
142
142
|
end
|
143
143
|
|
144
144
|
def miss_error(path, miss)
|
data/lib/dense/parser.rb
CHANGED
@@ -3,6 +3,17 @@ module Dense::Path::Parser include ::Raabro
|
|
3
3
|
|
4
4
|
# piece parsers bottom to top
|
5
5
|
|
6
|
+
def rxnames(i)
|
7
|
+
|
8
|
+
rex(:rxnames, i, %r{
|
9
|
+
/(
|
10
|
+
\\[\/bfnrt] |
|
11
|
+
\\u[0-9a-fA-F]{4} |
|
12
|
+
[^/\b\f\n\r\t]
|
13
|
+
)*/[imxouesn]*
|
14
|
+
}x)
|
15
|
+
end
|
16
|
+
|
6
17
|
def dqname(i)
|
7
18
|
|
8
19
|
rex(:qname, i, %r{
|
@@ -26,7 +37,8 @@ module Dense::Path::Parser include ::Raabro
|
|
26
37
|
end
|
27
38
|
|
28
39
|
def dot(i); str(nil, i, '.'); end
|
29
|
-
def
|
40
|
+
def comma_or_semicolon(i); rex(nil, i, / *[,;] */); end
|
41
|
+
|
30
42
|
def bend(i); str(nil, i, ']'); end
|
31
43
|
def bstart(i); str(nil, i, '['); end
|
32
44
|
def blank(i); str(:blank, i, ''); end
|
@@ -43,15 +55,23 @@ module Dense::Path::Parser include ::Raabro
|
|
43
55
|
/(
|
44
56
|
(-?\d+)?:(-?\d+)?:(-?\d+)? |
|
45
57
|
(-?\d+)?:(-?\d+)? |
|
58
|
+
(-?\d+)?,(\d+)? |
|
46
59
|
-?\d+
|
47
60
|
)/x)
|
48
61
|
end
|
49
62
|
|
50
63
|
def escape(i); rex(:esc, i, /\\[.*]/); end
|
51
64
|
|
52
|
-
def bindex(i)
|
53
|
-
|
54
|
-
|
65
|
+
def bindex(i)
|
66
|
+
alt(:index, i, :dqname, :sqname, :star, :ses, :rxnames, :name, :blank)
|
67
|
+
end
|
68
|
+
def bindexes(i)
|
69
|
+
jseq(:bindexes, i, :bindex, :comma_or_semicolon)
|
70
|
+
end
|
71
|
+
|
72
|
+
def simple_index(i)
|
73
|
+
alt(:index, i, :off, :escape, :star, :rxnames, :name)
|
74
|
+
end
|
55
75
|
|
56
76
|
def dotdot(i); str(:dotdot, i, '.'); end
|
57
77
|
def dotdotstar(i); rex(:dotdotstar, i, /(\.\.\*|\.\[\*\])/); end
|
@@ -67,10 +87,21 @@ module Dense::Path::Parser include ::Raabro
|
|
67
87
|
# rewrite parsed tree
|
68
88
|
|
69
89
|
def rewrite_ses(t)
|
70
|
-
|
71
|
-
|
72
|
-
|
90
|
+
|
91
|
+
s = t.string
|
92
|
+
|
93
|
+
if (a = s.split(',')).length == 2
|
94
|
+
{ start: a[0].to_i, count: a[1].to_i }
|
95
|
+
else
|
96
|
+
a = s.split(':').collect { |e| e.empty? ? nil : e.to_i }
|
97
|
+
if a[1] == nil && a[2] == nil
|
98
|
+
a[0]
|
99
|
+
else
|
100
|
+
{ start: a[0], end: a[1], step: a[2] }
|
101
|
+
end
|
102
|
+
end
|
73
103
|
end
|
104
|
+
|
74
105
|
def rewrite_esc(t); t.string[1, 1]; end
|
75
106
|
def rewrite_star(t); :star; end
|
76
107
|
def rewrite_dotdot(t); :dot; end
|
@@ -84,6 +115,30 @@ module Dense::Path::Parser include ::Raabro
|
|
84
115
|
|
85
116
|
def rewrite_blank(t); nil; end
|
86
117
|
|
118
|
+
ENCODINGS = {
|
119
|
+
'u' => 'UTF-8', 'e' => 'EUC-JP', 's' => 'Windows-31J', 'n' => 'ASCII-8BIT' }
|
120
|
+
R_ENCODINGS = ENCODINGS
|
121
|
+
.inject({}) { |h, (k, v)| h[v] = k; h }
|
122
|
+
|
123
|
+
def rewrite_rxnames(t)
|
124
|
+
|
125
|
+
m = t.string.match(/\A\/(.+)\/([imxuesn]*)\z/)
|
126
|
+
|
127
|
+
s = m[1]
|
128
|
+
|
129
|
+
e = ENCODINGS[(m[2].match(/[uesn]/) || [])[0]]
|
130
|
+
#s = s.force_encoding(e) if e
|
131
|
+
s = s.encode(e) if e
|
132
|
+
|
133
|
+
flags = 0
|
134
|
+
flags = flags | Regexp::EXTENDED if m[2].index('x')
|
135
|
+
flags = flags | Regexp::IGNORECASE if m[2].index('i')
|
136
|
+
#flags = flags | Regexp::MULTILINE if m[2].index('m')
|
137
|
+
flags = flags | Regexp::FIXEDENCODING if e
|
138
|
+
|
139
|
+
Regexp.new(s, flags)
|
140
|
+
end
|
141
|
+
|
87
142
|
def rewrite_qname(t); t.string[1..-2]; end
|
88
143
|
def rewrite_name(t); t.string; end
|
89
144
|
|
data/lib/dense/path.rb
CHANGED
@@ -8,7 +8,7 @@ class Dense::Path
|
|
8
8
|
@original = s
|
9
9
|
|
10
10
|
fail ArgumentError.new(
|
11
|
-
"
|
11
|
+
"argument is a #{s.class}, not a String"
|
12
12
|
) unless s.is_a?(String)
|
13
13
|
|
14
14
|
s = ".#{s}" \
|
@@ -124,8 +124,13 @@ class Dense::Path
|
|
124
124
|
return [ nil ] unless o.is_a?(Array)
|
125
125
|
|
126
126
|
be = k[:start] || 0
|
127
|
-
|
128
|
-
st =
|
127
|
+
|
128
|
+
en, st =
|
129
|
+
if co = k[:count]
|
130
|
+
[ be + co - 1, 1 ]
|
131
|
+
else
|
132
|
+
[ k[:end] || o.length - 1, k[:step] || 1 ]
|
133
|
+
end
|
129
134
|
|
130
135
|
Range.new(be, en).step(st).to_a
|
131
136
|
end
|
@@ -134,12 +139,18 @@ class Dense::Path
|
|
134
139
|
|
135
140
|
return _resolve_hash_key(o, k) if k.is_a?(Hash)
|
136
141
|
|
137
|
-
|
142
|
+
if o.is_a?(Hash)
|
143
|
+
|
144
|
+
return o.keys.select { |ok| ok =~ k } if k.is_a?(Regexp)
|
145
|
+
[ k.to_s ]
|
146
|
+
|
147
|
+
else # o is a Array
|
138
148
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
149
|
+
case k
|
150
|
+
when /\Afirst\z/i then [ 0 ]
|
151
|
+
when /\Alast\z/i then [ -1 ]
|
152
|
+
else [ k ]
|
153
|
+
end
|
143
154
|
end
|
144
155
|
end
|
145
156
|
|
@@ -251,12 +262,19 @@ class Dense::Path
|
|
251
262
|
|
252
263
|
case elt
|
253
264
|
when Hash
|
254
|
-
s =
|
265
|
+
s =
|
266
|
+
if elt[:count]
|
267
|
+
[ elt[:start], elt[:count] ].collect(&:to_s).join(',')
|
268
|
+
else
|
269
|
+
[ "#{elt[:start]}:#{elt[:end]}", elt[:step] ].compact.join(':')
|
270
|
+
end
|
255
271
|
in_array ? s : "[#{s}]"
|
256
272
|
when Array
|
257
|
-
"[#{elt.map { |e| _to_s(e, true) }.join('
|
273
|
+
"[#{elt.map { |e| _to_s(e, true) }.join(';')}#{elt.size < 2 ? ';' : ''}]"
|
258
274
|
when String
|
259
275
|
_str_to_s(elt, in_array)
|
276
|
+
when Regexp
|
277
|
+
_rex_to_s(elt)
|
260
278
|
when :star
|
261
279
|
'*'
|
262
280
|
when :dot
|
@@ -278,5 +296,12 @@ class Dense::Path
|
|
278
296
|
return "[#{elt.inspect}]" if s =~ /["']/
|
279
297
|
s
|
280
298
|
end
|
299
|
+
|
300
|
+
def _rex_to_s(r)
|
301
|
+
|
302
|
+
r.fixed_encoding? ?
|
303
|
+
r.inspect + (Dense::Path::Parser::R_ENCODINGS[r.encoding.name] || '') :
|
304
|
+
r.inspect
|
305
|
+
end
|
281
306
|
end # Dense::Path
|
282
307
|
|
metadata
CHANGED
@@ -1,19 +1,22 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dense
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: raabro
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
17
20
|
- - ">="
|
18
21
|
- !ruby/object:Gem::Version
|
19
22
|
version: 1.1.5
|
@@ -21,6 +24,9 @@ dependencies:
|
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.1'
|
24
30
|
- - ">="
|
25
31
|
- !ruby/object:Gem::Version
|
26
32
|
version: 1.1.5
|
@@ -30,14 +36,14 @@ dependencies:
|
|
30
36
|
requirements:
|
31
37
|
- - "~>"
|
32
38
|
- !ruby/object:Gem::Version
|
33
|
-
version: '3.
|
39
|
+
version: '3.7'
|
34
40
|
type: :development
|
35
41
|
prerelease: false
|
36
42
|
version_requirements: !ruby/object:Gem::Requirement
|
37
43
|
requirements:
|
38
44
|
- - "~>"
|
39
45
|
- !ruby/object:Gem::Version
|
40
|
-
version: '3.
|
46
|
+
version: '3.7'
|
41
47
|
description: Fetching deep in a dense structure. A kind of bastard of JSONPath.
|
42
48
|
email:
|
43
49
|
- jmettraux+flor@gmail.com
|
@@ -74,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
74
80
|
version: '0'
|
75
81
|
requirements: []
|
76
82
|
rubyforge_project:
|
77
|
-
rubygems_version: 2.6
|
83
|
+
rubygems_version: 2.7.6
|
78
84
|
signing_key:
|
79
85
|
specification_version: 4
|
80
86
|
summary: fetching deep in a dense structure
|