ruby-rego 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 (124) hide show
  1. checksums.yaml +7 -0
  2. data/.reek.yml +80 -0
  3. data/.vscode/extensions.json +19 -0
  4. data/.vscode/launch.json +35 -0
  5. data/.vscode/settings.json +25 -0
  6. data/.vscode/tasks.json +117 -0
  7. data/.yardopts +12 -0
  8. data/ARCHITECTURE.md +39 -0
  9. data/CHANGELOG.md +25 -0
  10. data/CODE_OF_CONDUCT.md +10 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +183 -0
  13. data/RELEASING.md +37 -0
  14. data/Rakefile +38 -0
  15. data/SECURITY.md +26 -0
  16. data/Steepfile +10 -0
  17. data/TODO.md +35 -0
  18. data/benchmark/builtin_calls.rb +29 -0
  19. data/benchmark/complex_policy.rb +19 -0
  20. data/benchmark/comprehensions.rb +19 -0
  21. data/benchmark/simple_rules.rb +20 -0
  22. data/examples/README.md +27 -0
  23. data/examples/sample_config.yaml +2 -0
  24. data/examples/simple_policy.rego +7 -0
  25. data/examples/validation_policy.rego +11 -0
  26. data/exe/rego-validate +6 -0
  27. data/lib/ruby/rego/ast/base.rb +95 -0
  28. data/lib/ruby/rego/ast/binary_op.rb +64 -0
  29. data/lib/ruby/rego/ast/call.rb +27 -0
  30. data/lib/ruby/rego/ast/composite.rb +48 -0
  31. data/lib/ruby/rego/ast/comprehension.rb +63 -0
  32. data/lib/ruby/rego/ast/every.rb +37 -0
  33. data/lib/ruby/rego/ast/import.rb +32 -0
  34. data/lib/ruby/rego/ast/literal.rb +70 -0
  35. data/lib/ruby/rego/ast/module.rb +32 -0
  36. data/lib/ruby/rego/ast/package.rb +22 -0
  37. data/lib/ruby/rego/ast/query.rb +63 -0
  38. data/lib/ruby/rego/ast/reference.rb +58 -0
  39. data/lib/ruby/rego/ast/rule.rb +114 -0
  40. data/lib/ruby/rego/ast/unary_op.rb +42 -0
  41. data/lib/ruby/rego/ast/variable.rb +22 -0
  42. data/lib/ruby/rego/ast.rb +17 -0
  43. data/lib/ruby/rego/builtins/aggregates.rb +124 -0
  44. data/lib/ruby/rego/builtins/base.rb +95 -0
  45. data/lib/ruby/rego/builtins/collections/array_ops.rb +103 -0
  46. data/lib/ruby/rego/builtins/collections/object_ops.rb +120 -0
  47. data/lib/ruby/rego/builtins/collections/set_ops.rb +51 -0
  48. data/lib/ruby/rego/builtins/collections.rb +137 -0
  49. data/lib/ruby/rego/builtins/comparisons/casts.rb +139 -0
  50. data/lib/ruby/rego/builtins/comparisons.rb +84 -0
  51. data/lib/ruby/rego/builtins/numeric_helpers.rb +56 -0
  52. data/lib/ruby/rego/builtins/registry.rb +199 -0
  53. data/lib/ruby/rego/builtins/registry_helpers.rb +27 -0
  54. data/lib/ruby/rego/builtins/strings/case_ops.rb +22 -0
  55. data/lib/ruby/rego/builtins/strings/concat.rb +19 -0
  56. data/lib/ruby/rego/builtins/strings/formatting.rb +35 -0
  57. data/lib/ruby/rego/builtins/strings/helpers.rb +62 -0
  58. data/lib/ruby/rego/builtins/strings/number_helpers.rb +48 -0
  59. data/lib/ruby/rego/builtins/strings/search.rb +63 -0
  60. data/lib/ruby/rego/builtins/strings/split.rb +19 -0
  61. data/lib/ruby/rego/builtins/strings/substring.rb +22 -0
  62. data/lib/ruby/rego/builtins/strings/trim.rb +42 -0
  63. data/lib/ruby/rego/builtins/strings/trim_helpers.rb +62 -0
  64. data/lib/ruby/rego/builtins/strings.rb +58 -0
  65. data/lib/ruby/rego/builtins/types.rb +89 -0
  66. data/lib/ruby/rego/call_name.rb +55 -0
  67. data/lib/ruby/rego/cli.rb +1122 -0
  68. data/lib/ruby/rego/compiled_module.rb +114 -0
  69. data/lib/ruby/rego/compiler.rb +1097 -0
  70. data/lib/ruby/rego/environment/overrides.rb +33 -0
  71. data/lib/ruby/rego/environment/reference_resolution.rb +86 -0
  72. data/lib/ruby/rego/environment.rb +230 -0
  73. data/lib/ruby/rego/environment_pool.rb +71 -0
  74. data/lib/ruby/rego/error_handling.rb +58 -0
  75. data/lib/ruby/rego/error_payload.rb +34 -0
  76. data/lib/ruby/rego/errors.rb +196 -0
  77. data/lib/ruby/rego/evaluator/assignment_support.rb +126 -0
  78. data/lib/ruby/rego/evaluator/binding_helpers.rb +60 -0
  79. data/lib/ruby/rego/evaluator/comprehension_evaluator.rb +182 -0
  80. data/lib/ruby/rego/evaluator/expression_dispatch.rb +45 -0
  81. data/lib/ruby/rego/evaluator/expression_evaluator.rb +492 -0
  82. data/lib/ruby/rego/evaluator/object_literal_evaluator.rb +52 -0
  83. data/lib/ruby/rego/evaluator/operator_evaluator.rb +163 -0
  84. data/lib/ruby/rego/evaluator/query_node_builder.rb +38 -0
  85. data/lib/ruby/rego/evaluator/reference_key_resolver.rb +50 -0
  86. data/lib/ruby/rego/evaluator/reference_resolver.rb +352 -0
  87. data/lib/ruby/rego/evaluator/rule_evaluator/bindings.rb +70 -0
  88. data/lib/ruby/rego/evaluator/rule_evaluator.rb +550 -0
  89. data/lib/ruby/rego/evaluator/rule_value_provider.rb +56 -0
  90. data/lib/ruby/rego/evaluator/variable_collector.rb +221 -0
  91. data/lib/ruby/rego/evaluator.rb +174 -0
  92. data/lib/ruby/rego/lexer/number_reader.rb +68 -0
  93. data/lib/ruby/rego/lexer/stream.rb +137 -0
  94. data/lib/ruby/rego/lexer/string_reader.rb +90 -0
  95. data/lib/ruby/rego/lexer/template_string_reader.rb +62 -0
  96. data/lib/ruby/rego/lexer.rb +206 -0
  97. data/lib/ruby/rego/location.rb +73 -0
  98. data/lib/ruby/rego/memoization.rb +67 -0
  99. data/lib/ruby/rego/parser/collections.rb +173 -0
  100. data/lib/ruby/rego/parser/expressions.rb +216 -0
  101. data/lib/ruby/rego/parser/precedence.rb +42 -0
  102. data/lib/ruby/rego/parser/query.rb +139 -0
  103. data/lib/ruby/rego/parser/references.rb +115 -0
  104. data/lib/ruby/rego/parser/rules.rb +310 -0
  105. data/lib/ruby/rego/parser.rb +210 -0
  106. data/lib/ruby/rego/policy.rb +50 -0
  107. data/lib/ruby/rego/result.rb +91 -0
  108. data/lib/ruby/rego/token.rb +206 -0
  109. data/lib/ruby/rego/unifier.rb +451 -0
  110. data/lib/ruby/rego/value.rb +379 -0
  111. data/lib/ruby/rego/version.rb +7 -0
  112. data/lib/ruby/rego/with_modifiers/with_modifier.rb +37 -0
  113. data/lib/ruby/rego/with_modifiers/with_modifier_applier.rb +48 -0
  114. data/lib/ruby/rego/with_modifiers/with_modifier_builtin_override.rb +128 -0
  115. data/lib/ruby/rego/with_modifiers/with_modifier_context.rb +120 -0
  116. data/lib/ruby/rego/with_modifiers/with_modifier_path_key_resolver.rb +42 -0
  117. data/lib/ruby/rego/with_modifiers/with_modifier_path_override.rb +99 -0
  118. data/lib/ruby/rego/with_modifiers/with_modifier_root_scope.rb +58 -0
  119. data/lib/ruby/rego.rb +72 -0
  120. data/sig/objspace.rbs +4 -0
  121. data/sig/psych.rbs +7 -0
  122. data/sig/rego_validate.rbs +382 -0
  123. data/sig/ruby/rego.rbs +2150 -0
  124. metadata +172 -0
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Naming/PredicatePrefix
4
+
5
+ require_relative "base"
6
+ require_relative "registry"
7
+
8
+ module Ruby
9
+ module Rego
10
+ module Builtins
11
+ # Built-in type predicates.
12
+ module Types
13
+ TYPE_PREDICATES = {
14
+ "is_string" => :is_string,
15
+ "is_number" => :is_number,
16
+ "is_boolean" => :is_boolean,
17
+ "is_array" => :is_array,
18
+ "is_object" => :is_object,
19
+ "is_set" => :is_set,
20
+ "is_null" => :is_null
21
+ }.freeze
22
+
23
+ # @return [Ruby::Rego::Builtins::BuiltinRegistry]
24
+ def self.register!
25
+ registry = BuiltinRegistry.instance
26
+
27
+ TYPE_PREDICATES.each do |name, handler|
28
+ register_predicate(registry, name, handler)
29
+ end
30
+
31
+ registry
32
+ end
33
+
34
+ def self.register_predicate(registry, name, handler)
35
+ return if registry.registered?(name)
36
+
37
+ registry.register(name, 1) { |value| public_send(handler, value) }
38
+ end
39
+ private_class_method :register_predicate
40
+
41
+ # @param value [Ruby::Rego::Value]
42
+ # @return [Ruby::Rego::BooleanValue]
43
+ def self.is_string(value)
44
+ BooleanValue.new(value.is_a?(StringValue))
45
+ end
46
+
47
+ # @param value [Ruby::Rego::Value]
48
+ # @return [Ruby::Rego::BooleanValue]
49
+ def self.is_number(value)
50
+ BooleanValue.new(value.is_a?(NumberValue))
51
+ end
52
+
53
+ # @param value [Ruby::Rego::Value]
54
+ # @return [Ruby::Rego::BooleanValue]
55
+ def self.is_boolean(value)
56
+ BooleanValue.new(value.is_a?(BooleanValue))
57
+ end
58
+
59
+ # @param value [Ruby::Rego::Value]
60
+ # @return [Ruby::Rego::BooleanValue]
61
+ def self.is_array(value)
62
+ BooleanValue.new(value.is_a?(ArrayValue))
63
+ end
64
+
65
+ # @param value [Ruby::Rego::Value]
66
+ # @return [Ruby::Rego::BooleanValue]
67
+ def self.is_object(value)
68
+ BooleanValue.new(value.is_a?(ObjectValue))
69
+ end
70
+
71
+ # @param value [Ruby::Rego::Value]
72
+ # @return [Ruby::Rego::BooleanValue]
73
+ def self.is_set(value)
74
+ BooleanValue.new(value.is_a?(SetValue))
75
+ end
76
+
77
+ # @param value [Ruby::Rego::Value]
78
+ # @return [Ruby::Rego::BooleanValue]
79
+ def self.is_null(value)
80
+ BooleanValue.new(value.is_a?(NullValue))
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ Ruby::Rego::Builtins::Types.register!
88
+
89
+ # rubocop:enable Naming/PredicatePrefix
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "ast"
4
+
5
+ module Ruby
6
+ module Rego
7
+ # Shared call name resolution helpers.
8
+ # NOTE: Internal helper module, not a stable public API.
9
+ module CallName
10
+ module_function
11
+
12
+ def call_name(node)
13
+ return node.name if node.is_a?(AST::Variable)
14
+ return node.to_s if node.is_a?(String) || node.is_a?(Symbol)
15
+ return reference_call_name(node) if node.is_a?(AST::Reference)
16
+
17
+ nil
18
+ end
19
+
20
+ def reference_call_name(reference)
21
+ base_name = reference_base_name(reference)
22
+ return nil unless base_name
23
+
24
+ segments = reference_call_segments(reference.path)
25
+ return nil unless segments
26
+
27
+ ([base_name] + segments).join(".")
28
+ end
29
+
30
+ def reference_base_name(reference)
31
+ base = reference.base
32
+ base.is_a?(AST::Variable) ? base.name : nil
33
+ end
34
+
35
+ def reference_call_segments(path)
36
+ segments = path.map { |segment| dot_ref_segment_value(segment) }
37
+ return nil if segments.any?(&:nil?)
38
+
39
+ segments.compact
40
+ end
41
+
42
+ def dot_ref_segment_value(segment)
43
+ value = segment.value
44
+ case segment
45
+ when AST::DotRefArg
46
+ return value.to_s if value.is_a?(String) || value.is_a?(Symbol)
47
+ when AST::BracketRefArg
48
+ return value.value.to_s if value.is_a?(AST::StringLiteral)
49
+ end
50
+
51
+ nil
52
+ end
53
+ end
54
+ end
55
+ end