field_mask_parser 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/field_mask_parser/node.rb +13 -6
- data/lib/field_mask_parser/parser/deep_hash_builder.rb +53 -0
- data/lib/field_mask_parser/parser/deep_hash_node.rb +25 -0
- data/lib/field_mask_parser/parser.rb +11 -41
- data/lib/field_mask_parser/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 268dcafa5e3c30786903d78669b94b076f518b114c0ebb62a50c6a78b0873cb5
|
4
|
+
data.tar.gz: 58d51f75abcd111c40a349fbbff7955b02eb01f211453a9d4845dae2aac4e537
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 376e5ce91f5cd5fd92d1b87d4226e3220c004fed05960a289286aad6bd5c657fcae691e7dd965c86779ff5fbccc80e0e59b0994a8d850926c0b34c10fac1e71b
|
7
|
+
data.tar.gz: 9b2a71040e43de2ce5e8d95b4ea39e3b1c5450b82928e2bea1346c7443e37612dbf00288c4478998f95b70d6170952ae49447ffd722c95f4e62f4d5757c1de32
|
data/Gemfile.lock
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
module FieldMaskParser
|
2
2
|
class Node
|
3
|
-
attr_reader :name, :attrs, :assocs
|
3
|
+
attr_reader :name, :is_leaf, :attrs, :assocs
|
4
4
|
|
5
5
|
# @param [Symbol | NilClass] name nil when being top-level node
|
6
|
+
# @param [bool] is_leaf
|
6
7
|
# @param [<Symbol>] attrs
|
7
8
|
# @param [Set<Node>] assocs
|
8
|
-
def initialize(name:)
|
9
|
-
@name
|
10
|
-
@
|
11
|
-
@
|
9
|
+
def initialize(name:, is_leaf:)
|
10
|
+
@name = name
|
11
|
+
@is_leaf = is_leaf
|
12
|
+
@attrs = []
|
13
|
+
@assocs = []
|
12
14
|
end
|
13
15
|
|
14
16
|
# @param [Symbol] f
|
@@ -22,7 +24,12 @@ module FieldMaskParser
|
|
22
24
|
end
|
23
25
|
|
24
26
|
def to_h
|
25
|
-
{
|
27
|
+
{
|
28
|
+
name: @name,
|
29
|
+
is_leaf: @is_leaf,
|
30
|
+
attrs: @attrs,
|
31
|
+
assocs: @assocs.map(&:to_h)
|
32
|
+
}
|
26
33
|
end
|
27
34
|
end
|
28
35
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module FieldMaskParser
|
2
|
+
class Parser
|
3
|
+
# HashBuilder build nested hash from paths (string array).
|
4
|
+
# ex.
|
5
|
+
# param: ["id", "facebook_uid", "detail", "detail.id", "profile.name"]
|
6
|
+
# return: {
|
7
|
+
# :id => <is_leaf: true, children: {}>,
|
8
|
+
# :facebook_uid => <is_leaf: true, children: {}>,
|
9
|
+
# :detail => <is_leaf: true, children: {
|
10
|
+
# :id => <is_leaf: true, children: {}>
|
11
|
+
# }>,
|
12
|
+
# :profile => <is_leaf: false, children: {
|
13
|
+
# :name => <is_leaf: true, children: {}>
|
14
|
+
# }>
|
15
|
+
# }
|
16
|
+
class DeepHashBuilder
|
17
|
+
class << self
|
18
|
+
# @param [<String>] paths
|
19
|
+
# @return [{ Symbol => Hash }]
|
20
|
+
def build(paths)
|
21
|
+
h = {}
|
22
|
+
paths.each do |path|
|
23
|
+
deep_push!(h, path.split('.').map(&:strip).map(&:to_sym))
|
24
|
+
end
|
25
|
+
h
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# @param [Hash] h
|
31
|
+
# @param [<String>] field_list
|
32
|
+
def deep_push!(h, field_list)
|
33
|
+
if field_list.size < 1
|
34
|
+
# Do nothing
|
35
|
+
return
|
36
|
+
end
|
37
|
+
|
38
|
+
f = field_list.first
|
39
|
+
f_rest = field_list[1..-1]
|
40
|
+
|
41
|
+
if !h[f]
|
42
|
+
h[f] = DeepHashNode.new
|
43
|
+
end
|
44
|
+
if f_rest.size == 0
|
45
|
+
h[f].is_leaf = true
|
46
|
+
end
|
47
|
+
|
48
|
+
deep_push!(h[f].children, f_rest)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module FieldMaskParser
|
2
|
+
class Parser
|
3
|
+
class DeepHashNode
|
4
|
+
attr_accessor :is_leaf
|
5
|
+
attr_reader :children
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@is_leaf = false
|
9
|
+
@children = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [Symbol] field
|
13
|
+
# @param [DeepHashNode] n
|
14
|
+
def push_child(field, n)
|
15
|
+
@children[field] = n
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param [DeepHashNode] other
|
19
|
+
# @reutrn [bool]
|
20
|
+
def ==(other)
|
21
|
+
is_leaf == other.is_leaf && children == other.children
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,49 +1,18 @@
|
|
1
|
+
require 'field_mask_parser/parser/deep_hash_builder'
|
2
|
+
require 'field_mask_parser/parser/deep_hash_node'
|
3
|
+
|
1
4
|
module FieldMaskParser
|
2
5
|
class Parser
|
3
|
-
# HashBuilder build nested hash from paths (string array).
|
4
|
-
# ex.
|
5
|
-
# param: ["id", "facebook_uid", "detail.id", "detail.email"]
|
6
|
-
# return: {:id=>{}, :facebook_uid=>{}, :detail=>{:id=>{}, :email=>{}}}
|
7
|
-
class HashBuilder
|
8
|
-
class << self
|
9
|
-
# @param [<String>] paths
|
10
|
-
# @return [{ Symbol => Hash }]
|
11
|
-
def build(paths)
|
12
|
-
h = {}
|
13
|
-
paths.each do |path|
|
14
|
-
deep_push!(h, path.split('.').map(&:strip).map(&:to_sym))
|
15
|
-
end
|
16
|
-
h
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
# @param [Hash] h
|
22
|
-
# @param [<String>] field_list
|
23
|
-
def deep_push!(h, field_list)
|
24
|
-
if field_list.size < 1
|
25
|
-
# Do nothing
|
26
|
-
return
|
27
|
-
end
|
28
|
-
f = field_list.first
|
29
|
-
if !h[f]
|
30
|
-
h[f] = {}
|
31
|
-
end
|
32
|
-
deep_push!(h[f], field_list[1..-1])
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
6
|
# @param [<String>] paths
|
38
7
|
def initialize(paths:, root:, dispatcher: nil)
|
39
|
-
@attrs_or_assocs =
|
8
|
+
@attrs_or_assocs = DeepHashBuilder.build(paths)
|
40
9
|
@root = root
|
41
10
|
@dispatcher = dispatcher || Dispatcher::ActiveRecordDispatcher.new
|
42
11
|
end
|
43
12
|
|
44
13
|
# @reutrn [Node]
|
45
14
|
def parse
|
46
|
-
r = Node.new(name: nil)
|
15
|
+
r = Node.new(name: nil, is_leaf: false)
|
47
16
|
set_attrs_and_assocs!(r, @attrs_or_assocs, @root)
|
48
17
|
r
|
49
18
|
end
|
@@ -51,19 +20,20 @@ module FieldMaskParser
|
|
51
20
|
private
|
52
21
|
|
53
22
|
# @param [Node] node
|
54
|
-
# @param [
|
23
|
+
# @param [{ Symbol => DeepHashNode }] attrs_or_assocs
|
55
24
|
# @param [Class] klass inheriting ActiveRecord::Base
|
56
25
|
def set_attrs_and_assocs!(node, attrs_or_assocs, klass)
|
57
|
-
attrs_or_assocs.each do |name,
|
26
|
+
attrs_or_assocs.each do |name, dhn|
|
58
27
|
case @dispatcher.dispatch(klass, name)
|
59
28
|
when Dispatcher::Type::ATTRIBUTE
|
29
|
+
# NOTE: If dhn.is_leaf is false, it is invalid. But ignore it now.
|
60
30
|
node.push_attr(name)
|
61
31
|
when Dispatcher::Type::ASSOCIATION
|
62
|
-
n = Node.new(name: name)
|
32
|
+
n = Node.new(name: name, is_leaf: dhn.is_leaf)
|
63
33
|
node.push_assoc(n)
|
64
|
-
if
|
34
|
+
if dhn.children.size > 0
|
65
35
|
_klass = get_assoc_klass(klass, name)
|
66
|
-
set_attrs_and_assocs!(n,
|
36
|
+
set_attrs_and_assocs!(n, dhn.children, _klass)
|
67
37
|
end
|
68
38
|
when Dispatcher::Type::UNKNOWN
|
69
39
|
# Ignore invalid field
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: field_mask_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nao Minami
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -104,6 +104,8 @@ files:
|
|
104
104
|
- lib/field_mask_parser/dispatcher/type.rb
|
105
105
|
- lib/field_mask_parser/node.rb
|
106
106
|
- lib/field_mask_parser/parser.rb
|
107
|
+
- lib/field_mask_parser/parser/deep_hash_builder.rb
|
108
|
+
- lib/field_mask_parser/parser/deep_hash_node.rb
|
107
109
|
- lib/field_mask_parser/version.rb
|
108
110
|
homepage: https://github.com/south37/field_mask_parser
|
109
111
|
licenses:
|