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 = false) ⇒ Object
TODO: default to false.
- .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
66 67 68 69 |
# File 'lib/command_search/normalizer.rb', line 66 def cast_numeric!(node) return unless node[:type] == :number node[:value] = node[:value].to_f end |
.cast_regex!(node) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/command_search/normalizer.rb', line 53 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 47 48 49 50 51 |
# 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 time_parsed = Time.parse(str) rescue nil if time_parsed search_node[:value] = [time_parsed, time_parsed + 1] else search_node[:value] = nil return end 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
71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/command_search/normalizer.rb', line 71 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
83 84 85 86 |
# File 'lib/command_search/normalizer.rb', line 83 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 = false) ⇒ Object
TODO: default to false
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/command_search/normalizer.rb', line 123 def normalize!(ast, fields, cast_all = false) 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
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/command_search/normalizer.rb', line 88 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
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/command_search/normalizer.rb', line 104 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 |