query-ruby 0.1.0

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.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.github/dependabot.yml +15 -0
  3. data/.github/workflows/ci.yml +38 -0
  4. data/.gitignore +30 -0
  5. data/.node-version +1 -0
  6. data/.npm-version +1 -0
  7. data/.prettierignore +2 -0
  8. data/.rspec +1 -0
  9. data/.rubocop.yml +130 -0
  10. data/.ruby-version +1 -0
  11. data/.tool-versions +3 -0
  12. data/Gemfile +22 -0
  13. data/Gemfile.lock +249 -0
  14. data/LICENSE +19 -0
  15. data/README.md +3 -0
  16. data/Rakefile +5 -0
  17. data/VERSION +1 -0
  18. data/bin/query +52 -0
  19. data/lib/query/combiner.rb +33 -0
  20. data/lib/query/decompiler.rb +41 -0
  21. data/lib/query/node/base_10.rb +22 -0
  22. data/lib/query/node/base_16.rb +17 -0
  23. data/lib/query/node/base_2.rb +17 -0
  24. data/lib/query/node/base_8.rb +17 -0
  25. data/lib/query/node/boolean.rb +46 -0
  26. data/lib/query/node/decimal.rb +25 -0
  27. data/lib/query/node/key.rb +17 -0
  28. data/lib/query/node/key_value.rb +23 -0
  29. data/lib/query/node/number.rb +27 -0
  30. data/lib/query/node/operator.rb +35 -0
  31. data/lib/query/node/part.rb +21 -0
  32. data/lib/query/node/query.rb +17 -0
  33. data/lib/query/node/range.rb +23 -0
  34. data/lib/query/node/string.rb +17 -0
  35. data/lib/query/node/text.rb +17 -0
  36. data/lib/query/node/value.rb +27 -0
  37. data/lib/query/node.rb +9 -0
  38. data/lib/query/parser/boolean.rb +24 -0
  39. data/lib/query/parser/key.rb +11 -0
  40. data/lib/query/parser/key_value.rb +13 -0
  41. data/lib/query/parser/number.rb +158 -0
  42. data/lib/query/parser/operator.rb +42 -0
  43. data/lib/query/parser/part.rb +11 -0
  44. data/lib/query/parser/query.rb +15 -0
  45. data/lib/query/parser/range.rb +32 -0
  46. data/lib/query/parser/string.rb +44 -0
  47. data/lib/query/parser/text.rb +40 -0
  48. data/lib/query/parser/value.rb +11 -0
  49. data/lib/query/parser/whitespace.rb +19 -0
  50. data/lib/query/parser.rb +21 -0
  51. data/lib/query/version.rb +6 -0
  52. data/lib/query-ruby.rb +14 -0
  53. data/lib/query.rb +29 -0
  54. data/package-lock.json +14 -0
  55. data/package.json +7 -0
  56. data/query-ruby.gemspec +26 -0
  57. data/spec/query_spec.rb +73 -0
  58. data/spec/spec_helper.rb +1 -0
  59. metadata +182 -0
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Base16 < Node
6
+ attr_accessor :base_16
7
+
8
+ def initialize(parsed)
9
+ self.base_16 = parsed
10
+ end
11
+
12
+ def evaluate(**_args)
13
+ base_16.to_i(16)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Base2 < Node
6
+ attr_accessor :base_2
7
+
8
+ def initialize(parsed)
9
+ self.base_2 = parsed
10
+ end
11
+
12
+ def evaluate(**_args)
13
+ base_2.to_i(2)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Base8 < Node
6
+ attr_accessor :base_8
7
+
8
+ def initialize(parsed)
9
+ self.base_8 = parsed
10
+ end
11
+
12
+ def evaluate(**_args)
13
+ base_8.to_i(8)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Boolean < Node
6
+ attr_accessor :boolean
7
+
8
+ BOOLEANS = {
9
+ "true" => true,
10
+ "t" => true,
11
+ "True" => true,
12
+ "TRUE" => true,
13
+ "T" => true,
14
+ "yes" => true,
15
+ "y" => true,
16
+ "Yes" => true,
17
+ "YES" => true,
18
+ "Y" => true,
19
+ "on" => true,
20
+ "On" => true,
21
+ "ON" => true,
22
+ "false" => false,
23
+ "f" => false,
24
+ "False" => false,
25
+ "FALSE" => false,
26
+ "F" => false,
27
+ "no" => false,
28
+ "n" => false,
29
+ "No" => false,
30
+ "NO" => false,
31
+ "N" => false,
32
+ "off" => false,
33
+ "Off" => false,
34
+ "OFF" => false,
35
+ }
36
+
37
+ def initialize(parsed)
38
+ self.boolean = parsed
39
+ end
40
+
41
+ def evaluate(**args)
42
+ BOOLEANS.fetch(boolean)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Decimal < Node
6
+ attr_accessor :decimal, :exponent
7
+
8
+ def initialize(parsed)
9
+ self.decimal = parsed.delete(:decimal)
10
+
11
+ if parsed.key?(:exponent)
12
+ self.exponent = Value.new(parsed.delete(:exponent))
13
+ end
14
+ end
15
+
16
+ def evaluate(**args)
17
+ if exponent
18
+ BigDecimal(decimal) * 10 ** exponent.evaluate(**args)
19
+ else
20
+ BigDecimal(decimal)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Key < Node
6
+ attr_accessor :key
7
+
8
+ def initialize(parsed)
9
+ self.key = parsed.presence
10
+ end
11
+
12
+ def evaluate(**args)
13
+ key.to_sym
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class KeyValue < Node
6
+ attr_accessor :key, :operator, :value
7
+
8
+ def initialize(parsed)
9
+ self.key = Key.new(parsed.delete(:key))
10
+ self.operator = Operator.new(parsed.delete(:operator))
11
+ self.value = Value.new(parsed.delete(:value))
12
+ end
13
+
14
+ def evaluate(**args)
15
+ {
16
+ key: key.evaluate(**args),
17
+ operator: operator.evaluate(**args),
18
+ value: value.evaluate(**args)
19
+ }
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Number < Node
6
+ attr_accessor :value
7
+
8
+ def initialize(parsed)
9
+ if parsed.key?(:decimal)
10
+ self.value = Decimal.new(parsed.delete(:decimal))
11
+ elsif parsed.key?(:base_16)
12
+ self.value = Base16.new(parsed.delete(:base_16))
13
+ elsif parsed.key?(:base_8)
14
+ self.value = Base8.new(parsed.delete(:base_8))
15
+ elsif parsed.key?(:base_2)
16
+ self.value = Base2.new(parsed.delete(:base_2))
17
+ else
18
+ self.value = Base10.new(parsed.delete(:base_10))
19
+ end
20
+ end
21
+
22
+ def evaluate(**args)
23
+ value.evaluate(**args)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Operator < Node
6
+ attr_accessor :operator
7
+
8
+ OPERATORS = {
9
+ "^" => "^",
10
+ "$" => "$",
11
+ ">=" => ">=",
12
+ "=>" => ">=",
13
+ "<=" => "<=",
14
+ "=<" => "<=",
15
+ "<" => "<",
16
+ ">" => ">",
17
+ "!" => "!",
18
+ ":::" => ":",
19
+ "::" => ":",
20
+ ":" => ":",
21
+ "=" => "=",
22
+ "==" => "=",
23
+ "===" => "=",
24
+ }
25
+
26
+ def initialize(parsed)
27
+ self.operator = parsed
28
+ end
29
+
30
+ def evaluate(**args)
31
+ OPERATORS.fetch(operator)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Part < Node
6
+ attr_accessor :part
7
+
8
+ def initialize(parsed)
9
+ if parsed.key?(:key_value)
10
+ self.part = KeyValue.new(parsed.delete(:key_value))
11
+ elsif parsed.key?(:text)
12
+ self.part = Text.new(parsed.delete(:text))
13
+ end
14
+ end
15
+
16
+ def evaluate(**args)
17
+ part&.evaluate(**args)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Query < Node
6
+ attr_accessor :parts
7
+
8
+ def initialize(parsed)
9
+ self.parts = (parsed.presence || []).map { |part| Part.new(part) }
10
+ end
11
+
12
+ def evaluate(**args)
13
+ parts.map { |part| part.evaluate(**args) }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Range < Node
6
+ attr_accessor :left, :right, :operator
7
+
8
+ def initialize(parsed)
9
+ self.left = Value.new(parsed.delete(:left))
10
+ self.operator = parsed.delete(:operator)
11
+ self.right = Value.new(parsed.delete(:right))
12
+ end
13
+
14
+ def evaluate(**args)
15
+ if operator == "..."
16
+ (left.evaluate(**args))...(right.evaluate(**args))
17
+ else
18
+ (left.evaluate(**args))..(right.evaluate(**args))
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class String < Node
6
+ attr_accessor :string
7
+
8
+ def initialize(parsed)
9
+ self.string = parsed
10
+ end
11
+
12
+ def evaluate(**args)
13
+ string.to_s
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Text < Node
6
+ attr_accessor :text
7
+
8
+ def initialize(parsed)
9
+ self.text = parsed.presence
10
+ end
11
+
12
+ def evaluate(**args)
13
+ text
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ class Value < Node
6
+ attr_accessor :value
7
+
8
+ def initialize(parsed)
9
+ if parsed.key?(:key_value)
10
+ self.value = KeyValue.new(parsed.delete(:key_value))
11
+ elsif parsed.key?(:boolean)
12
+ self.value = Boolean.new(parsed.delete(:boolean))
13
+ elsif parsed.key?(:number)
14
+ self.value = Number.new(parsed.delete(:number))
15
+ elsif parsed.key?(:string)
16
+ self.value = String.new(parsed.delete(:string))
17
+ elsif parsed.key?(:range)
18
+ self.value = Range.new(parsed.delete(:range))
19
+ end
20
+ end
21
+
22
+ def evaluate(**args)
23
+ value.evaluate(**args)
24
+ end
25
+ end
26
+ end
27
+ end
data/lib/query/node.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Node
5
+ def evaluate(**_args)
6
+ Object::Nothing.new
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Parser
5
+ class Boolean < Language
6
+ def special
7
+ str("...") | str("..") | Whitespace | Operator
8
+ end
9
+
10
+ def root
11
+ (
12
+ (
13
+ str("true") | str("t") | str("True") | str("TRUE") | str("T") |
14
+ str("yes") | str("y") | str("Yes") | str("YES") | str("Y") |
15
+ str("on") | str("On") | str("ON")
16
+ str("false") | str("f") | str("False") | str("FALSE") |
17
+ str("F") | str("no") | str("n") | str("No") | str("NO") |
18
+ str("N") | str("off") | str("Off") | str("OFF")
19
+ ) << special.present
20
+ ).aka(:boolean)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Parser
5
+ class Key < Language
6
+ def root
7
+ str("_").absent << (Whitespace.absent << Operator.absent << any).repeat(1)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Parser
5
+ class KeyValue < Language
6
+ def root
7
+ (Key.aka(:key) << Operator.aka(:operator) << Value.aka(:value)).aka(
8
+ :key_value
9
+ )
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Parser
5
+ class Number < Language
6
+ def special
7
+ str("...") | str("..") | Whitespace | Operator
8
+ end
9
+
10
+ def zero
11
+ str("0")
12
+ end
13
+
14
+ def one
15
+ str("1")
16
+ end
17
+
18
+ def two
19
+ str("2")
20
+ end
21
+
22
+ def three
23
+ str("3")
24
+ end
25
+
26
+ def four
27
+ str("4")
28
+ end
29
+
30
+ def five
31
+ str("5")
32
+ end
33
+
34
+ def six
35
+ str("6")
36
+ end
37
+
38
+ def seven
39
+ str("7")
40
+ end
41
+
42
+ def eight
43
+ str("8")
44
+ end
45
+
46
+ def nine
47
+ str("9")
48
+ end
49
+
50
+ def dot
51
+ str(".")
52
+ end
53
+
54
+ def a
55
+ str("a") | str("A")
56
+ end
57
+
58
+ def b
59
+ str("b") | str("B")
60
+ end
61
+
62
+ def c
63
+ str("c") | str("C")
64
+ end
65
+
66
+ def d
67
+ str("d") | str("D")
68
+ end
69
+
70
+ def e
71
+ str("e") | str("E")
72
+ end
73
+
74
+ def f
75
+ str("f") | str("F")
76
+ end
77
+
78
+ def o
79
+ str("o") | str("O")
80
+ end
81
+
82
+ def x
83
+ str("x") | str("X")
84
+ end
85
+
86
+ def underscore
87
+ str("_")
88
+ end
89
+
90
+ def base_16_digit
91
+ zero | one | two | three | four | five | six | seven | eight | nine |
92
+ a | b | c | d | e | f
93
+ end
94
+
95
+ def base_10_digit
96
+ zero | one | two | three | four | five | six | seven | eight | nine
97
+ end
98
+
99
+ def base_8_digit
100
+ zero | one | two | three | four | five | six | seven
101
+ end
102
+
103
+ def base_2_digit
104
+ zero | one
105
+ end
106
+
107
+ def base_16_whole
108
+ base_16_digit << (underscore.ignore | base_16_digit).repeat
109
+ end
110
+
111
+ def base_10_whole
112
+ base_10_digit << (underscore.ignore | base_10_digit).repeat
113
+ end
114
+
115
+ def base_8_whole
116
+ base_8_digit << (underscore.ignore | base_8_digit).repeat
117
+ end
118
+
119
+ def base_2_whole
120
+ base_2_digit << (underscore.ignore | base_2_digit).repeat
121
+ end
122
+
123
+ def exponent
124
+ (e << Number).aka(:exponent)
125
+ end
126
+
127
+ def decimal
128
+ (base_10_whole << dot << base_10_whole).aka(:decimal) << exponent.maybe
129
+ end
130
+
131
+ def base_16_number
132
+ zero.ignore << x.ignore << base_16_whole
133
+ end
134
+
135
+ def base_10_number
136
+ base_10_whole.aka(:whole) << exponent.maybe
137
+ end
138
+
139
+ def base_8_number
140
+ zero.ignore << o.ignore << base_8_whole
141
+ end
142
+
143
+ def base_2_number
144
+ zero.ignore << b.ignore << base_2_whole
145
+ end
146
+
147
+ def root
148
+ (
149
+ (
150
+ decimal.aka(:decimal) | base_16_number.aka(:base_16) |
151
+ base_8_number.aka(:base_8) | base_2_number.aka(:base_2) |
152
+ base_10_number.aka(:base_10)
153
+ ) << special.present
154
+ ).aka(:number)
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Parser
5
+ class Operator < Language
6
+ OPERATORS = [
7
+ "^",
8
+ "$",
9
+ ">=",
10
+ "=>",
11
+ "<=",
12
+ "=<",
13
+ "<",
14
+ ">",
15
+ "!",
16
+ ]
17
+
18
+ MODIFIERS = [
19
+ ":::",
20
+ "::",
21
+ ":",
22
+ "===",
23
+ "==",
24
+ "=",
25
+ "",
26
+ ]
27
+
28
+ def root
29
+ OPERATORS.flat_map do |operator|
30
+ MODIFIERS.map do |modifier|
31
+ str("#{operator}#{modifier}") |
32
+ str("#{modifier}#{operator}") |
33
+ str(operator)
34
+ end.reduce(&:|).then { operator }
35
+ end.reduce(&:|) |
36
+ MODIFIERS.compact_blank.map do |modifier|
37
+ str(modifier)
38
+ end.reduce(&:|)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Parser
5
+ class Part < Language
6
+ def root
7
+ KeyValue | Text
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Parser
5
+ class Query < Language
6
+ def whitespace?
7
+ Whitespace.maybe
8
+ end
9
+
10
+ def root
11
+ whitespace? << (Part << Whitespace).repeat | any.repeat | whitespace?
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Query
4
+ class Parser
5
+ class Range < Language
6
+ def operator
7
+ str("...") | str("..")
8
+ end
9
+
10
+ def whitespace?
11
+ Whitespace.maybe
12
+ end
13
+
14
+ def special
15
+ str("...") | str("..") | Whitespace | Operator
16
+ end
17
+
18
+ def root
19
+ (
20
+ (
21
+ (
22
+ Number.aka(:left) << operator.aka(:operator) << Number.aka(:right)
23
+ ) |
24
+ (
25
+ String.aka(:left) << operator.aka(:operator) << String.aka(:right)
26
+ )
27
+ ) << special.present
28
+ ).aka(:range)
29
+ end
30
+ end
31
+ end
32
+ end