Class: NodeQuery::NodeRules

Inherits:
Object
  • Object
show all
Defined in:
lib/node_query/node_rules.rb

Constant Summary collapse

KEYWORDS =
%i[not_includes includes not in not_in gt gte lt lte]

Instance Method Summary collapse

Constructor Details

#initialize(rules, adapter:) ⇒ NodeRules

Initialize a NodeRules.



9
10
11
12
# File 'lib/node_query/node_rules.rb', line 9

def initialize(rules, adapter:)
  @rules = rules
  @adapter = adapter
end

Instance Method Details

#match_node?(node) ⇒ Boolean

Check if the node matches the rules.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/node_query/node_rules.rb', line 53

def match_node?(node)
  flat_hash(@rules).keys.all? do |multi_keys|
    last_key = multi_keys.last
    actual =
      KEYWORDS.include?(last_key) ?
             NodeQuery::Helper.get_target_node(node, multi_keys[0...-1].join('.'), @adapter) :
             NodeQuery::Helper.get_target_node(node, multi_keys.join('.'), @adapter)
    expected = expected_value(@rules, multi_keys)
    expected = NodeQuery::Helper.evaluate_node_value(node, expected, @adapter) if expected.is_a?(String)
    case last_key
    when :includes
      actual.any? { |actual_value| match_value?(actual_value, expected) }
    when :not_includes
      actual.all? { |actual_value| !match_value?(actual_value, expected) }
    when :not
      !match_value?(actual, expected)
    when :in
      expected.any? { |expected_value| match_value?(actual, expected_value) }
    when :not_in
      expected.all? { |expected_value| !match_value?(actual, expected_value) }
    when :gt
      actual > expected
    when :gte
      actual >= expected
    when :lt
      actual < expected
    when :lte
      actual <= expected
    else
      match_value?(actual, expected)
    end
  end
end

#query_nodes(node, options = {}) ⇒ Array<Node>

Query nodes by the rules.

Options Hash (options):

  • :including_self (boolean)

    if query the current node, default is ture

  • :stop_at_first_match (boolean)

    if stop at first match, default is false

  • :recursive (boolean)

    if recursively query child nodes, default is true



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/node_query/node_rules.rb', line 21

def query_nodes(node, options = {})
  options = { including_self: true, stop_at_first_match: false, recursive: true }.merge(options)
  if options[:including_self] && !options[:recursive]
    return match_node?(node) ? [node] : []
  end

  matching_nodes = []
  if options[:including_self] && match_node?(node)
    matching_nodes.push(node)
    return matching_nodes if options[:stop_at_first_match]
  end
  if options[:recursive]
    NodeQuery::Helper.handle_recursive_child(node, @adapter) do |child_node|
      if match_node?(child_node)
        matching_nodes.push(child_node)
        break if options[:stop_at_first_match]
      end
    end
  else
    @adapter.get_children(node).each do |child_node|
      if match_node?(child_node)
        matching_nodes.push(child_node)
        break if options[:stop_at_first_match]
      end
    end
  end
  matching_nodes
end