oso-oso 0.23.0 → 0.26.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +7 -6
- data/Makefile +1 -1
- data/ext/oso-oso/lib/libpolar.dylib +0 -0
- data/ext/oso-oso/lib/libpolar.so +0 -0
- data/ext/oso-oso/lib/polar.dll +0 -0
- data/lib/oso/oso.rb +5 -33
- data/lib/oso/polar/data/adapter/active_record_adapter.rb +57 -0
- data/lib/oso/polar/data/adapter.rb +22 -0
- data/lib/oso/polar/data/filter.rb +59 -0
- data/lib/oso/polar/data.rb +4 -0
- data/lib/oso/polar/data_filtering.rb +0 -190
- data/lib/oso/polar/errors.rb +0 -1
- data/lib/oso/polar/expression.rb +1 -1
- data/lib/oso/polar/ffi/error.rb +4 -22
- data/lib/oso/polar/ffi/polar.rb +60 -35
- data/lib/oso/polar/ffi/query.rb +48 -22
- data/lib/oso/polar/ffi/{source.rb → rust_string.rb} +9 -3
- data/lib/oso/polar/ffi.rb +28 -20
- data/lib/oso/polar/host.rb +35 -10
- data/lib/oso/polar/polar.rb +76 -16
- data/lib/oso/polar/query.rb +19 -10
- data/lib/oso/polar.rb +1 -0
- data/lib/oso/version.rb +1 -1
- data/lib/oso.rb +0 -1
- metadata +7 -5
- data/lib/oso/polar/ffi/message.rb +0 -40
- data/lib/oso/polar/ffi/query_event.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c6a70f052d3142dbaf1f8d9c699a7f3c6697060
|
4
|
+
data.tar.gz: 9820ca345e2b1bb85c31183a3f43a1748d412d77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '08cabc94530a44164fef27de25cac7477fc8906b6a4766197b003c4f629332ce4a24b88fc96e7fa78e305c23f0e16f0f5df5481bc7ffb82e5c51a9ffb7cd260c'
|
7
|
+
data.tar.gz: f534eec40e00a8c10dc9379843e8b08dc4bc95bd6526e4c00e0a88aaca11877b31bf643d82e934fe0b01ccdb1d957ae25c3fa069875e46ea7765634313bd43ec
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
oso-oso (0.
|
4
|
+
oso-oso (0.26.0)
|
5
5
|
ffi (~> 1.0)
|
6
6
|
|
7
7
|
GEM
|
@@ -21,14 +21,14 @@ GEM
|
|
21
21
|
arel (9.0.0)
|
22
22
|
ast (2.4.2)
|
23
23
|
backport (1.2.0)
|
24
|
-
benchmark (0.
|
24
|
+
benchmark (0.2.0)
|
25
25
|
byebug (11.1.3)
|
26
26
|
coderay (1.1.3)
|
27
27
|
concurrent-ruby (1.1.9)
|
28
28
|
diff-lcs (1.4.4)
|
29
29
|
e2mmap (0.1.0)
|
30
30
|
ffi (1.15.4)
|
31
|
-
i18n (1.8.
|
31
|
+
i18n (1.8.11)
|
32
32
|
concurrent-ruby (~> 1.0)
|
33
33
|
jaro_winkler (1.5.4)
|
34
34
|
maruku (0.7.3)
|
@@ -49,7 +49,7 @@ GEM
|
|
49
49
|
rainbow (3.0.0)
|
50
50
|
rake (12.3.3)
|
51
51
|
regexp_parser (2.1.1)
|
52
|
-
reverse_markdown (2.
|
52
|
+
reverse_markdown (2.1.1)
|
53
53
|
nokogiri
|
54
54
|
rexml (3.2.5)
|
55
55
|
rspec (3.10.0)
|
@@ -64,7 +64,7 @@ GEM
|
|
64
64
|
rspec-mocks (3.10.2)
|
65
65
|
diff-lcs (>= 1.2.0, < 2.0)
|
66
66
|
rspec-support (~> 3.10.0)
|
67
|
-
rspec-support (3.10.
|
67
|
+
rspec-support (3.10.3)
|
68
68
|
rubocop (0.89.1)
|
69
69
|
parallel (~> 1.10)
|
70
70
|
parser (>= 2.7.1.1)
|
@@ -97,12 +97,13 @@ GEM
|
|
97
97
|
tilt (2.0.10)
|
98
98
|
tzinfo (1.2.9)
|
99
99
|
thread_safe (~> 0.1)
|
100
|
-
unicode-display_width (1.
|
100
|
+
unicode-display_width (1.8.0)
|
101
101
|
yard (0.9.26)
|
102
102
|
|
103
103
|
PLATFORMS
|
104
104
|
ruby
|
105
105
|
x86_64-darwin-20
|
106
|
+
x86_64-linux
|
106
107
|
|
107
108
|
DEPENDENCIES
|
108
109
|
activerecord
|
data/Makefile
CHANGED
Binary file
|
data/ext/oso-oso/lib/libpolar.so
CHANGED
Binary file
|
data/ext/oso-oso/lib/polar.dll
CHANGED
Binary file
|
data/lib/oso/oso.rb
CHANGED
@@ -181,27 +181,8 @@ module Oso
|
|
181
181
|
# @param resource_cls The resource being accessed.
|
182
182
|
#
|
183
183
|
# @return A query for resources accessible to the actor.
|
184
|
-
def authorized_query(actor, action, resource_cls)
|
185
|
-
|
186
|
-
|
187
|
-
results = query_rule(
|
188
|
-
'allow',
|
189
|
-
actor,
|
190
|
-
action,
|
191
|
-
resource,
|
192
|
-
bindings: { 'resource' => type_constraint(resource, resource_cls) },
|
193
|
-
accept_expression: true
|
194
|
-
)
|
195
|
-
|
196
|
-
results = results.each_with_object([]) do |result, out|
|
197
|
-
result.each do |key, val|
|
198
|
-
out.push({ 'bindings' => { key => host.to_polar(val) } })
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
::Oso::Polar::DataFiltering::FilterPlan
|
203
|
-
.parse(self, results, get_class_name(resource_cls))
|
204
|
-
.build_query
|
184
|
+
def authorized_query(actor, action, resource_cls)
|
185
|
+
new_authorized_query(actor, action, resource_cls)
|
205
186
|
end
|
206
187
|
|
207
188
|
# Determine the resources of type +resource_cls+ that +actor+
|
@@ -213,20 +194,11 @@ module Oso
|
|
213
194
|
#
|
214
195
|
# @return A list of resources accessible to the actor.
|
215
196
|
def authorized_resources(actor, action, resource_cls)
|
216
|
-
|
217
|
-
return [] if q.nil?
|
218
|
-
|
219
|
-
host.types[get_class_name resource_cls].exec_query[q]
|
197
|
+
host.adapter.execute_query authorized_query(actor, action, resource_cls)
|
220
198
|
end
|
221
199
|
|
222
|
-
|
223
|
-
|
224
|
-
# `register_class` or by defining `build_query`, `exec_query` and
|
225
|
-
# `combine_query` methods on the class object.
|
226
|
-
def set_data_filtering_query_defaults(build_query: nil, exec_query: nil, combine_query: nil)
|
227
|
-
host.build_query = build_query if build_query
|
228
|
-
host.exec_query = exec_query if exec_query
|
229
|
-
host.combine_query = combine_query if combine_query
|
200
|
+
def data_filtering_adapter=(adapter)
|
201
|
+
host.adapter = adapter
|
230
202
|
end
|
231
203
|
end
|
232
204
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Oso
|
4
|
+
module Polar
|
5
|
+
module Data
|
6
|
+
class Adapter
|
7
|
+
# Example data filtering adapter for ActiveRecord
|
8
|
+
class ActiveRecordAdapter < Adapter
|
9
|
+
def build_query(filter) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
10
|
+
types = filter.types
|
11
|
+
query = filter.relations.reduce(filter.model.all) do |q, rel|
|
12
|
+
rec = types[rel.left].fields[rel.name]
|
13
|
+
q.joins(
|
14
|
+
"INNER JOIN #{rel.right.table_name} ON " \
|
15
|
+
"#{rel.left.table_name}.#{rec.my_field} = " \
|
16
|
+
"#{rel.right.table_name}.#{rec.other_field}"
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
filter.conditions.map do |conjs|
|
21
|
+
conjs.reduce(query) do |q, conj|
|
22
|
+
q.where(*sqlize(conj))
|
23
|
+
end
|
24
|
+
end.reduce(:or).distinct
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute_query(query)
|
28
|
+
query.to_a
|
29
|
+
end
|
30
|
+
|
31
|
+
OPS = {
|
32
|
+
'Eq' => '=', 'In' => 'IN', 'Nin' => 'NOT IN', 'Neq' => '!=',
|
33
|
+
'Lt' => '<', 'Gt' => '>', 'Leq' => '<=', 'Geq' => '>='
|
34
|
+
}.freeze
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def sqlize(cond)
|
39
|
+
args = []
|
40
|
+
lhs = add_side cond.left, args
|
41
|
+
rhs = add_side cond.right, args
|
42
|
+
args.unshift "#{lhs} #{OPS[cond.cmp]} #{rhs}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_side(side, args)
|
46
|
+
if side.is_a? ::Oso::Polar::Data::Filter::Projection
|
47
|
+
"#{side.source.table_name}.#{side.field || side.source.primary_key}"
|
48
|
+
else
|
49
|
+
args.push side
|
50
|
+
'?'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Oso
|
4
|
+
module Polar
|
5
|
+
module Data
|
6
|
+
# Abstract data adapter
|
7
|
+
#
|
8
|
+
# An Adapter has to implement two methods.
|
9
|
+
class Adapter
|
10
|
+
# Make a query object from a filter
|
11
|
+
def build_query(_filter)
|
12
|
+
raise "build_query not implemented for #{self}"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Make a list of objects from a query
|
16
|
+
def execute_query(_query)
|
17
|
+
raise "execute_query not implemented for #{self}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Oso
|
4
|
+
module Polar
|
5
|
+
# Data filtering interface for Ruby
|
6
|
+
module Data
|
7
|
+
# Abstract data filter used by the Adapter API.
|
8
|
+
class Filter
|
9
|
+
attr_reader :model, :relations, :conditions, :types
|
10
|
+
|
11
|
+
def initialize(model:, relations:, conditions:, types:)
|
12
|
+
@model = model
|
13
|
+
@relations = relations
|
14
|
+
@conditions = conditions
|
15
|
+
@types = types
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.parse(polar, blob)
|
19
|
+
types = polar.host.types
|
20
|
+
model = types[blob['root']].klass.get
|
21
|
+
relations = blob['relations'].map do |rel|
|
22
|
+
Relation.parse(polar, *rel)
|
23
|
+
end
|
24
|
+
conditions = blob['conditions'].map do |disj|
|
25
|
+
disj.map { |conj| Condition.parse(polar, *conj) }
|
26
|
+
end
|
27
|
+
new(model: model, relations: relations, conditions: conditions, types: types)
|
28
|
+
end
|
29
|
+
|
30
|
+
Projection = Struct.new(:source, :field)
|
31
|
+
|
32
|
+
Relation = Struct.new(:left, :name, :right) do
|
33
|
+
def self.parse(polar, left, name, right)
|
34
|
+
Relation.new(polar.name_to_class(left), name, polar.name_to_class(right))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Condition = Struct.new(:left, :cmp, :right) do
|
39
|
+
def self.parse(polar, left, cmp, right)
|
40
|
+
Condition.new(parse_side(polar, left), cmp, parse_side(polar, right))
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.parse_side(polar, side)
|
44
|
+
key = side.keys.first
|
45
|
+
val = side[key]
|
46
|
+
case key
|
47
|
+
when 'Field'
|
48
|
+
Projection.new(polar.name_to_class(val[0]), val[1])
|
49
|
+
when 'Immediate'
|
50
|
+
polar.host.to_ruby('value' => [[val.keys.first, val.values.first]])
|
51
|
+
else
|
52
|
+
raise key
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -4,110 +4,6 @@ module Oso
|
|
4
4
|
module Polar
|
5
5
|
# Data filtering interface for Ruby
|
6
6
|
module DataFiltering
|
7
|
-
GETATTR = ->(x, attr) { attr.nil? ? x : x.send(attr) }
|
8
|
-
# Represents a set of filter sequences that should allow the host
|
9
|
-
# to obtain the records satisfying a query.
|
10
|
-
class FilterPlan
|
11
|
-
attr_reader :result_sets
|
12
|
-
|
13
|
-
def self.parse(polar, partials, class_name)
|
14
|
-
types = polar.host.serialize_types
|
15
|
-
parsed_json = polar.ffi.build_filter_plan(types, partials, 'resource', class_name)
|
16
|
-
result_sets = parsed_json['result_sets'].map do |rset|
|
17
|
-
ResultSet.parse polar, rset
|
18
|
-
end
|
19
|
-
|
20
|
-
new polar: polar, result_sets: result_sets
|
21
|
-
end
|
22
|
-
|
23
|
-
def initialize(polar:, result_sets:)
|
24
|
-
@polar = polar
|
25
|
-
@result_sets = result_sets
|
26
|
-
end
|
27
|
-
|
28
|
-
def build_query # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
29
|
-
combine = nil
|
30
|
-
result_sets.each_with_object([]) do |rs, qb|
|
31
|
-
rs.resolve_order.each_with_object({}) do |i, set_results|
|
32
|
-
req = rs.requests[i]
|
33
|
-
cs = req.ground(set_results)
|
34
|
-
typ = @polar.host.types[req.class_tag]
|
35
|
-
q = typ.build_query[cs]
|
36
|
-
if i != rs.result_id
|
37
|
-
set_results[i] = typ.exec_query[q]
|
38
|
-
else
|
39
|
-
combine = typ.combine_query
|
40
|
-
qb.push q
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end.reduce(&combine)
|
44
|
-
end
|
45
|
-
|
46
|
-
# Represents a sequence of filters for one set of results
|
47
|
-
class ResultSet
|
48
|
-
attr_reader :requests, :resolve_order, :result_id
|
49
|
-
|
50
|
-
def self.parse(polar, parsed_json)
|
51
|
-
resolve_order = parsed_json['resolve_order']
|
52
|
-
result_id = parsed_json['result_id']
|
53
|
-
requests = parsed_json['requests'].each_with_object({}) do |req, reqs|
|
54
|
-
reqs[req[0].to_i] = Request.parse(polar, req[1])
|
55
|
-
end
|
56
|
-
|
57
|
-
new resolve_order: resolve_order, result_id: result_id, requests: requests
|
58
|
-
end
|
59
|
-
|
60
|
-
def initialize(requests:, resolve_order:, result_id:)
|
61
|
-
@resolve_order = resolve_order
|
62
|
-
@requests = requests
|
63
|
-
@result_id = result_id
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Represents a filter for a result set
|
68
|
-
class Request
|
69
|
-
attr_reader :constraints, :class_tag
|
70
|
-
|
71
|
-
def self.parse(polar, parsed_json)
|
72
|
-
@polar = polar
|
73
|
-
constraints = parsed_json['constraints'].map do |con|
|
74
|
-
Filter.parse polar, con
|
75
|
-
end
|
76
|
-
class_tag = parsed_json['class_tag']
|
77
|
-
|
78
|
-
new(constraints: constraints, class_tag: class_tag)
|
79
|
-
end
|
80
|
-
|
81
|
-
def ground(results) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
|
82
|
-
xrefs, rest = constraints.partition do |c|
|
83
|
-
c.value.is_a?(Ref) and !c.value.result_id.nil?
|
84
|
-
end
|
85
|
-
|
86
|
-
yrefs, nrefs = xrefs.partition { |r| %w[In Eq].include? r.kind }
|
87
|
-
[[yrefs, 'In'], [nrefs, 'Nin']].each do |refs, kind|
|
88
|
-
refs.group_by { |f| f.value.result_id }.each do |rid, fils|
|
89
|
-
if fils.length > 1
|
90
|
-
value = results[rid].map { |r| fils.map { |f| GETATTR[r, f.value.field] } }
|
91
|
-
field = fils.map(&:field)
|
92
|
-
rest.push(Filter.new(kind: kind, value: value, field: field))
|
93
|
-
else
|
94
|
-
fil = fils[0]
|
95
|
-
field = fil.value.field
|
96
|
-
value = results[rid].map { |r| field.nil? ? r : r.send(field) }
|
97
|
-
rest.push(Filter.new(kind: kind, field: fil.field, value: value))
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
rest
|
102
|
-
end
|
103
|
-
|
104
|
-
def initialize(constraints:, class_tag:)
|
105
|
-
@constraints = constraints
|
106
|
-
@class_tag = class_tag
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
7
|
# Represents relationships between resources, eg. one-one or one-many
|
112
8
|
class Relation
|
113
9
|
attr_reader :kind, :other_type, :my_field, :other_field
|
@@ -124,92 +20,6 @@ module Oso
|
|
124
20
|
@other_field = other_field
|
125
21
|
end
|
126
22
|
end
|
127
|
-
|
128
|
-
# Represents field-field relationships on one resource.
|
129
|
-
class Field
|
130
|
-
attr_reader :field
|
131
|
-
|
132
|
-
def initialize(field:)
|
133
|
-
@field = field
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
# Represents field-field relationships on different resources.
|
138
|
-
class Ref
|
139
|
-
attr_reader :field, :result_id
|
140
|
-
|
141
|
-
def initialize(field:, result_id:)
|
142
|
-
@field = field
|
143
|
-
@result_id = result_id
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
# Represents a condition that must hold on a resource.
|
148
|
-
class Filter
|
149
|
-
attr_reader :kind, :field, :value
|
150
|
-
|
151
|
-
CHECKS = {
|
152
|
-
'Eq' => ->(a, b) { a == b },
|
153
|
-
'In' => ->(a, b) { b.include? a },
|
154
|
-
'Neq' => ->(a, b) { a != b },
|
155
|
-
'Nin' => ->(a, b) { !b.include?(a) },
|
156
|
-
'Contains' => ->(a, b) { a.include? b }
|
157
|
-
}.freeze
|
158
|
-
|
159
|
-
# Create a new predicate for data filtering.
|
160
|
-
# @param kind [String] Represents a condition. One of "Eq", "Neq", "In", "Contains".
|
161
|
-
# @param field The field the condition applies to.
|
162
|
-
# @param value The value with which to compare the field according to the condition.
|
163
|
-
def initialize(kind:, field:, value:)
|
164
|
-
@kind = kind
|
165
|
-
@field = field
|
166
|
-
@value = value
|
167
|
-
end
|
168
|
-
|
169
|
-
def ground(results)
|
170
|
-
return unless value.is_a? Ref
|
171
|
-
|
172
|
-
ref = value
|
173
|
-
@value = results[ref.result_id]
|
174
|
-
@value = value.map { |v| v.send ref.field } unless ref.field.nil?
|
175
|
-
end
|
176
|
-
|
177
|
-
def check(item) # rubocop:disable Metrics/AbcSize
|
178
|
-
val = value.is_a?(Field) ? item.send(value.field) : value
|
179
|
-
item = if field.nil?
|
180
|
-
item
|
181
|
-
elsif field.is_a? Array
|
182
|
-
field.map { |f| GETATTR[item, f] }
|
183
|
-
else
|
184
|
-
item.send field
|
185
|
-
end
|
186
|
-
CHECKS[@kind][item, val]
|
187
|
-
end
|
188
|
-
|
189
|
-
def self.parse(polar, constraint) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
190
|
-
kind = constraint['kind']
|
191
|
-
field = constraint['field']
|
192
|
-
value = constraint['value']
|
193
|
-
|
194
|
-
value_kind = value.keys.first
|
195
|
-
value = value[value_kind]
|
196
|
-
|
197
|
-
case value_kind
|
198
|
-
when 'Term'
|
199
|
-
value = polar.host.to_ruby value
|
200
|
-
when 'Ref'
|
201
|
-
child_field = value['field']
|
202
|
-
result_id = value['result_id']
|
203
|
-
value = Ref.new field: child_field, result_id: result_id
|
204
|
-
when 'Field'
|
205
|
-
value = Field.new field: value
|
206
|
-
else
|
207
|
-
raise "Unknown value kind `#{value_kind}`"
|
208
|
-
end
|
209
|
-
|
210
|
-
new kind: kind, field: field, value: value
|
211
|
-
end
|
212
|
-
end
|
213
23
|
end
|
214
24
|
end
|
215
25
|
end
|
data/lib/oso/polar/errors.rb
CHANGED
@@ -26,7 +26,6 @@ module Oso
|
|
26
26
|
class UnsupportedError < PolarRuntimeError; end
|
27
27
|
class PolarTypeError < PolarRuntimeError; end
|
28
28
|
class StackOverflowError < PolarRuntimeError; end
|
29
|
-
class FileLoadingError < PolarRuntimeError; end
|
30
29
|
|
31
30
|
# Errors originating from this side of the FFI boundary.
|
32
31
|
|
data/lib/oso/polar/expression.rb
CHANGED
data/lib/oso/polar/ffi/error.rb
CHANGED
@@ -6,29 +6,13 @@ module Oso
|
|
6
6
|
module Polar
|
7
7
|
module FFI
|
8
8
|
# Wrapper class for Error FFI pointer + operations.
|
9
|
-
class Error
|
10
|
-
def to_s
|
11
|
-
@to_s ||= read_string.force_encoding('UTF-8')
|
12
|
-
end
|
13
|
-
|
14
|
-
Rust = Module.new do
|
15
|
-
extend ::FFI::Library
|
16
|
-
ffi_lib FFI::LIB_PATH
|
17
|
-
|
18
|
-
attach_function :get, :polar_get_error, [], Error
|
19
|
-
attach_function :free, :string_free, [Error], :int32
|
20
|
-
end
|
21
|
-
private_constant :Rust
|
22
|
-
|
9
|
+
class Error
|
23
10
|
# Check for an FFI error and convert it into a Ruby exception.
|
24
11
|
#
|
25
12
|
# @return [::Oso::Polar::Error] if there's an FFI error.
|
26
13
|
# @return [::Oso::Polar::FFIErrorNotFound] if there isn't one.
|
27
|
-
def self.get(enrich_message) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
28
|
-
error =
|
29
|
-
return ::Oso::Polar::FFIErrorNotFound if error.null?
|
30
|
-
|
31
|
-
error = JSON.parse(error.to_s)
|
14
|
+
def self.get(error_str, enrich_message) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
15
|
+
error = JSON.parse(error_str.to_s)
|
32
16
|
msg = error['formatted']
|
33
17
|
kind, body = error['kind'].first
|
34
18
|
|
@@ -90,7 +74,7 @@ module Oso
|
|
90
74
|
# @param msg [String]
|
91
75
|
# @param details [Hash<String, Object>]
|
92
76
|
# @return [::Oso::Polar::PolarRuntimeError] the object converted into the expected format.
|
93
|
-
private_class_method def self.runtime_error(kind, msg:, details:)
|
77
|
+
private_class_method def self.runtime_error(kind, msg:, details:)
|
94
78
|
case kind
|
95
79
|
when 'Unsupported'
|
96
80
|
::Oso::Polar::UnsupportedError.new(msg, details: details)
|
@@ -98,8 +82,6 @@ module Oso
|
|
98
82
|
::Oso::Polar::PolarTypeError.new(msg, details: details)
|
99
83
|
when 'StackOverflow'
|
100
84
|
::Oso::Polar::StackOverflowError.new(msg, details: details)
|
101
|
-
when 'FileLoading'
|
102
|
-
::Oso::Polar::FileLoadingError.new(msg, details: details)
|
103
85
|
else
|
104
86
|
::Oso::Polar::PolarRuntimeError.new(msg, details: details)
|
105
87
|
end
|