dmn 0.0.2 → 0.0.4

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.
@@ -1,372 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DMN
4
- class LiteralExpression
5
- attr_reader :id, :text
6
-
7
- def self.from_json(json)
8
- LiteralExpression.new(id: json[:id], text: json[:text])
9
- end
10
-
11
- def initialize(id: nil, text:)
12
- @id = id
13
- @text = text&.strip
14
- end
15
-
16
- def tree
17
- @tree ||= DMN::Parser.parse(text)
18
- end
19
-
20
- def valid?
21
- return false if text.blank?
22
- tree.present?
23
- end
24
-
25
- def evaluate(variables = {})
26
- tree.eval(functions.merge(variables))
27
- end
28
-
29
- def functions
30
- builtins = LiteralExpression.builtin_functions
31
- custom = (DMN.config.functions || {})
32
- ActiveSupport::HashWithIndifferentAccess.new(builtins.merge(custom))
33
- end
34
-
35
- def named_functions
36
- # Initialize a set to hold the qualified names
37
- function_names = Set.new
38
-
39
- # Define a lambda for the recursive function
40
- walk_tree = lambda do |node|
41
- # If the node is a qualified name, add it to the set
42
- if node.is_a?(DMN::FunctionInvocation)
43
- function_names << node.fn_name.text_value
44
- end
45
-
46
- # Recursively walk the child nodes
47
- node.elements&.each do |child|
48
- walk_tree.call(child)
49
- end
50
- end
51
-
52
- # Start walking the tree from the root
53
- walk_tree.call(tree)
54
-
55
- # Return the array of functions
56
- function_names.to_a
57
- end
58
-
59
- def named_variables
60
- # Initialize a set to hold the qualified names
61
- qualified_names = Set.new
62
-
63
- # Define a lambda for the recursive function
64
- walk_tree = lambda do |node|
65
- # If the node is a qualified name, add it to the set
66
- if node.is_a?(DMN::QualifiedName)
67
- qualified_names << node.text_value
68
- end
69
-
70
- # Recursively walk the child nodes
71
- node.elements&.each do |child|
72
- walk_tree.call(child)
73
- end
74
- end
75
-
76
- # Start walking the tree from the root
77
- walk_tree.call(tree)
78
-
79
- # Return the array of qualified names
80
- qualified_names.to_a
81
- end
82
-
83
- def self.builtin_functions
84
- HashWithIndifferentAccess.new({
85
- # Conversion functions
86
- "string": ->(from) {
87
- return if from.nil?
88
- from.to_s
89
- },
90
- "number": ->(from) {
91
- return if from.nil?
92
- from.include?(".") ? from.to_f : from.to_i
93
- },
94
- # Boolean functions
95
- "not": ->(value) {
96
- if value == true || value == false
97
- !value
98
- end
99
- },
100
- "is defined": ->(value) {
101
- return if value.nil?
102
- !value.nil?
103
- },
104
- "get or else": ->(value, default) {
105
- value.nil? ? default : value
106
- },
107
- # String functions
108
- "substring": ->(string, start, length) {
109
- return if string.nil? || start.nil?
110
- return "" if length.nil?
111
- string[start - 1, length]
112
- },
113
- "substring before": ->(string, match) {
114
- return if string.nil? || match.nil?
115
- string.split(match).first
116
- },
117
- "substring after": ->(string, match) {
118
- return if string.nil? || match.nil?
119
- string.split(match).last
120
- },
121
- "string length": ->(string) {
122
- return if string.nil?
123
- string.length
124
- },
125
- "upper case": ->(string) {
126
- return if string.nil?
127
- string.upcase
128
- },
129
- "lower case": -> (string) {
130
- return if string.nil?
131
- string.downcase
132
- },
133
- "contains": ->(string, match) {
134
- return if string.nil? || match.nil?
135
- string.include?(match)
136
- },
137
- "starts with": ->(string, match) {
138
- return if string.nil? || match.nil?
139
- string.start_with?(match)
140
- },
141
- "ends with": ->(string, match) {
142
- return if string.nil? || match.nil?
143
- string.end_with?(match)
144
- },
145
- "matches": ->(string, match) {
146
- return if string.nil? || match.nil?
147
- string.match?(match)
148
- },
149
- "replace": ->(string, match, replacement) {
150
- return if string.nil? || match.nil? || replacement.nil?
151
- string.gsub(match, replacement)
152
- },
153
- "split": ->(string, match) {
154
- return if string.nil? || match.nil?
155
- string.split(match)
156
- },
157
- "strip": -> (string) {
158
- return if string.nil?
159
- string.strip
160
- },
161
- "extract": -> (string, pattern) {
162
- return if string.nil? || pattern.nil?
163
- string.match(pattern).captures
164
- },
165
- # Numeric functions
166
- "decimal": ->(n, scale) {
167
- return if n.nil? || scale.nil?
168
- n.round(scale)
169
- },
170
- "floor": ->(n) {
171
- return if n.nil?
172
- n.floor
173
- },
174
- "ceiling": ->(n) {
175
- return if n.nil?
176
- n.ceil
177
- },
178
- "round up": ->(n) {
179
- return if n.nil?
180
- n.ceil
181
- },
182
- "round down": ->(n) {
183
- return if n.nil?
184
- n.floor
185
- },
186
- "abs": ->(n) {
187
- return if n.nil?
188
- n.abs
189
- },
190
- "modulo": ->(n, divisor) {
191
- return if n.nil? || divisor.nil?
192
- n % divisor
193
- },
194
- "sqrt": ->(n) {
195
- return if n.nil?
196
- Math.sqrt(n)
197
- },
198
- "log": ->(n) {
199
- return if n.nil?
200
- Math.log(n)
201
- },
202
- "exp": ->(n) {
203
- return if n.nil?
204
- Math.exp(n)
205
- },
206
- "odd": ->(n) {
207
- return if n.nil?
208
- n.odd?
209
- },
210
- "even": ->(n) {
211
- return if n.nil?
212
- n.even?
213
- },
214
- "random number": ->(n) {
215
- return if n.nil?
216
- rand(n)
217
- },
218
- # List functions
219
- "list contains": ->(list, match) {
220
- return if list.nil?
221
- return false if match.nil?
222
- list.include?(match)
223
- },
224
- "count": ->(list) {
225
- return if list.nil?
226
- return 0 if list.empty?
227
- list.length
228
- },
229
- "min": ->(list) {
230
- return if list.nil?
231
- list.min
232
- },
233
- "max": ->(list) {
234
- return if list.nil?
235
- list.max
236
- },
237
- "sum": ->(list) {
238
- return if list.nil?
239
- list.sum
240
- },
241
- "product": ->(list) {
242
- return if list.nil?
243
- list.inject(:*)
244
- },
245
- "mean": ->(list) {
246
- return if list.nil?
247
- list.sum / list.length
248
- },
249
- "median": ->(list) {
250
- return if list.nil?
251
- list.sort[list.length / 2]
252
- },
253
- "stddev": ->(list) {
254
- return if list.nil?
255
- mean = list.sum / list.length.to_f
256
- Math.sqrt(list.map { |n| (n - mean)**2 }.sum / list.length)
257
- },
258
- "mode": ->(list) {
259
- return if list.nil?
260
- list.group_by(&:itself).values.max_by(&:size).first
261
- },
262
- "all": ->(list) {
263
- return if list.nil?
264
- list.all?
265
- },
266
- "any": ->(list) {
267
- return if list.nil?
268
- list.any?
269
- },
270
- "sublist": ->(list, start, length) {
271
- return if list.nil? || start.nil?
272
- return [] if length.nil?
273
- list[start - 1, length]
274
- },
275
- "append": ->(list, item) {
276
- return if list.nil?
277
- list + [item]
278
- },
279
- "concatenate": ->(list1, list2) {
280
- return [nil, nil] if list1.nil? && list2.nil?
281
- return [nil] + list2 if list1.nil?
282
- return list1 + [nil] if list2.nil?
283
- Array.wrap(list1) + Array.wrap(list2)
284
- },
285
- "insert before": ->(list, position, item) {
286
- return if list.nil? || position.nil?
287
- list.insert(position - 1, item)
288
- },
289
- "remove": ->(list, position) {
290
- return if list.nil? || position.nil?
291
- list.delete_at(position - 1); list
292
- },
293
- "reverse": ->(list) {
294
- return if list.nil?
295
- list.reverse
296
- },
297
- "index of": ->(list, match) {
298
- return if list.nil?
299
- return [] if match.nil?
300
- list.index(match) + 1
301
- },
302
- "union": ->(list1, list2) {
303
- return if list1.nil? || list2.nil?
304
- list1 | list2
305
- },
306
- "distinct values": ->(list) {
307
- return if list.nil?
308
- list.uniq
309
- },
310
- "duplicate values": ->(list) {
311
- return if list.nil?
312
- list.select { |e| list.count(e) > 1 }.uniq
313
- },
314
- "flatten": ->(list) {
315
- return if list.nil?
316
- list.flatten
317
- },
318
- "sort": ->(list) {
319
- return if list.nil?
320
- list.sort
321
- },
322
- "string join": ->(list, separator) {
323
- return if list.nil?
324
- list.join(separator)
325
- },
326
- # Context functions
327
- "get value": ->(context, name) {
328
- return if context.nil? || name.nil?
329
- context[name]
330
- },
331
- "context put": ->(context, name, value) {
332
- return if context.nil? || name.nil?
333
- context[name] = value; context
334
- },
335
- "context merge": ->(context1, context2) {
336
- return if context1.nil? || context2.nil?
337
- context1.merge(context2)
338
- },
339
- "get entries": ->(context) {
340
- return if context.nil?
341
- context.entries
342
- },
343
- # Temporal functions
344
- "now": ->() { Time.now },
345
- "today": ->() { Date.today },
346
- "day of week": ->(date) {
347
- return if date.nil?
348
- date.wday
349
- },
350
- "day of year": ->(date) {
351
- return if date.nil?
352
- date.yday
353
- },
354
- "week of year": ->(date) {
355
- return if date.nil?
356
- date.cweek
357
- },
358
- "month of year": ->(date) {
359
- return if date.nil?
360
- date.month
361
- },
362
- })
363
- end
364
-
365
- def as_json
366
- {
367
- id: id,
368
- text: text,
369
- }
370
- end
371
- end
372
- end