Module: CommandSearch::Normalizer
- Defined in:
- lib/command_search/normalizer.rb
Class Method Summary collapse
- .cast_bool!(field, node) ⇒ Object
- .cast_numeric!(node) ⇒ Object
- .cast_regex!(node) ⇒ Object
- .cast_time!(node) ⇒ Object
- .clean_comparison!(node, fields) ⇒ Object
- .dealias_key(key, fields) ⇒ Object
- .normalize!(ast, fields, cast_all = true) ⇒ Object
- .split_general_fields(node, fields) ⇒ Object
- .type_cast!(node, fields, cast_all) ⇒ Object
Class Method Details
.cast_bool!(field, node) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/command_search/normalizer.rb', line 7 def cast_bool!(field, node) type = field.is_a?(Hash) ? field[:type] : field if type == Boolean return if field.is_a?(Hash) && field[:general_search] && !node[:value][/\Atrue\Z|\Afalse\Z/i] node[:type] = Boolean node[:value] = !!node[:value][0][/t/i] return end return unless field.is_a?(Hash) && field[:allow_existence_boolean] return unless node[:type] == :str && node[:value][/\Atrue\Z|\Afalse\Z/i] node[:type] = :existence node[:value] = !!node[:value][0][/t/i] end |
.cast_numeric!(node) ⇒ Object
61 62 63 64 |
# File 'lib/command_search/normalizer.rb', line 61 def cast_numeric!(node) return unless node[:type] == :number node[:value] = node[:value].to_f end |
.cast_regex!(node) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/command_search/normalizer.rb', line 48 def cast_regex!(node) type = node[:type] raw = node[:value] return unless raw.is_a?(String) return if node[:value] == '' str = Regexp.escape(raw) return node[:value] = /#{str}/i unless type == :quote return node[:value] = /\b#{str}\b/ unless raw[/(\A\W)|(\W\Z)/] border_a = '(^|[^:+\w])' border_b = '($|[^:+\w])' node[:value] = Regexp.new(border_a + str + border_b) end |
.cast_time!(node) ⇒ Object
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 |
# File 'lib/command_search/normalizer.rb', line 21 def cast_time!(node) search_node = node[:value][1] search_node[:type] = Time str = search_node[:value] if str == str.to_i.to_s search_node[:value] = [Time.new(str), Time.new(str.to_i + 1)] else time_str = str.tr('._-', ' ') times = Chronic.parse(time_str, { guess: nil }) times ||= Chronic.parse(str, { guess: nil }) if times search_node[:value] = [times.first, times.last] else search_node[:value] = nil return end end return unless node[:type] == :compare op = node[:nest_op] if op == '<' || op == '>=' search_node[:value] = search_node[:value].first else search_node[:value] = search_node[:value].last search_node[:value] -= 1 end end |
.clean_comparison!(node, fields) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/command_search/normalizer.rb', line 66 def clean_comparison!(node, fields) val = node[:value] return unless fields[val[1][:value].to_sym] if fields[val[0][:value].to_sym] node[:compare_across_fields] = true return end flip_ops = { '<' => '>', '>' => '<', '<=' => '>=', '>=' => '<=' } node[:nest_op] = flip_ops[node[:nest_op]] node[:value].reverse! end |
.dealias_key(key, fields) ⇒ Object
78 79 80 81 |
# File 'lib/command_search/normalizer.rb', line 78 def dealias_key(key, fields) key = fields[key.to_sym] while fields[key.to_sym].is_a?(Symbol) key end |
.normalize!(ast, fields, cast_all = true) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/command_search/normalizer.rb', line 117 def normalize!(ast, fields, cast_all = true) ast.map! do |node| if node[:type] == :and || node[:type] == :or || node[:type] == :not normalize!(node[:value], fields, cast_all) next node end if node[:type] == :colon || node[:type] == :compare clean_comparison!(node, fields) if node[:type] == :compare key = dealias_key(node[:value][0][:value], fields) node[:value][0][:value] = key.to_s unless fields[key.to_sym] || fields[key.to_s] str_values = "#{key}#{node[:nest_op]}#{node[:value][1][:value]}" node = { type: :str, value: str_values } end end if node[:type] == :str || node[:type] == :quote || node[:type] == :number node = split_general_fields(node, fields) end if node[:type] == :or node[:value].each { |x| type_cast!(x, fields, cast_all) } else type_cast!(node, fields, cast_all) end node end end |
.split_general_fields(node, fields) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/command_search/normalizer.rb', line 83 def split_general_fields(node, fields) general_fields = fields.select { |k, v| v.is_a?(Hash) && v[:general_search] }.keys general_fields = ['__CommandSearch_dummy_key__'] if general_fields.empty? new_val = general_fields.map! do |field| { type: :colon, value: [ { value: field.to_s }, { value: node[:value], type: node[:type] } ] } end return new_val.first if new_val.count < 2 { type: :or, value: new_val } end |
.type_cast!(node, fields, cast_all) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/command_search/normalizer.rb', line 99 def type_cast!(node, fields, cast_all) (key_node, search_node) = node[:value] key = key_node[:value] field = fields[key.to_sym] || fields[key.to_s] return unless field type = field.is_a?(Class) ? field : field[:type] type = Numeric if type == Integer key_node[:field_type] = type cast_bool!(field, search_node) return cast_time!(node) if [Time, Date, DateTime].include?(type) return cast_numeric!(search_node) if Numeric == type if cast_all cast_regex!(search_node) else search_node[:type] = :str if search_node[:type] == :number end end |