rubanok 0.4.0 → 0.5.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/CHANGELOG.md +4 -0
- data/LICENSE.txt +1 -1
- data/README.md +24 -2
- data/lib/rubanok/dsl/mapping.rb +0 -4
- data/lib/rubanok/dsl/matching.rb +3 -7
- data/lib/rubanok/dsl/process.rb +72 -0
- data/lib/rubanok/processor.rb +7 -2
- data/lib/rubanok/version.rb +1 -1
- data/sig/rubanok/dsl/mapping.rbs +1 -3
- data/sig/rubanok/dsl/matching.rbs +5 -6
- data/sig/rubanok/dsl/process.rbs +23 -0
- data/sig/rubanok/processor.rbs +9 -0
- data/sig/typeprof.rb +10 -0
- metadata +13 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8233d2946a61205ae18864a6304de48bf1d89621c989e8e364ce6b7f55cce3b6
|
4
|
+
data.tar.gz: 5ee328fb4f857065e11750dc2a9a8f169c7eebd9120d86c0617594929ab7e1d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ca8ec88b1f4f86c30834c429cdc1acfe98a4e6ce1e19bf707acf9178f8a46c729c65e5a4549190ebd3781150362d396f72cd163441df3174b9adb4ddc876af9
|
7
|
+
data.tar.gz: cf3bd84216aa32ddf4dc2150213659ac70f52fef84dfe2842cdd7b80acc362042196e9385fa42d3dd84dae4b26ebea0e84eb0232692035b55c09a5b99e0c21ee
|
data/CHANGELOG.md
CHANGED
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2018-
|
3
|
+
Copyright (c) 2018-2024 Vladimir Dementyev
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -53,8 +53,8 @@ end
|
|
53
53
|
|
54
54
|
Requirements:
|
55
55
|
|
56
|
-
- Ruby ~> 2.
|
57
|
-
- (optional\*) Rails >=
|
56
|
+
- Ruby ~> 2.7
|
57
|
+
- (optional\*) Rails >= 6.0 (see older releases for Rails <6 support)
|
58
58
|
|
59
59
|
\* This gem has no dependency on Rails.
|
60
60
|
|
@@ -155,6 +155,28 @@ If in example above you will call `CourseSessionsProcessor.call(CourseSession, f
|
|
155
155
|
|
156
156
|
**NOTE:** Rubanok only matches exact values; more complex matching could be added in the future.
|
157
157
|
|
158
|
+
### Nested processors
|
159
|
+
|
160
|
+
You can use the `.process` method to define sub-processors (or nested processors). It's useful when you use nested params, for example:
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
class CourseSessionsProcessor < Rubanok::Processor
|
164
|
+
process :filter do
|
165
|
+
match :status do
|
166
|
+
having "draft" do
|
167
|
+
raw.where(draft: true)
|
168
|
+
end
|
169
|
+
|
170
|
+
having "deleted" do
|
171
|
+
raw.where.not(deleted_at: nil)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# You can also use .map or even .process here
|
176
|
+
end
|
177
|
+
end
|
178
|
+
```
|
179
|
+
|
158
180
|
### Default transformation
|
159
181
|
|
160
182
|
Sometimes it's useful to perform some transformations before **any** rule is activated.
|
data/lib/rubanok/dsl/mapping.rb
CHANGED
data/lib/rubanok/dsl/matching.rb
CHANGED
@@ -26,7 +26,7 @@ module Rubanok
|
|
26
26
|
super(fields, activate_on: activate_on, activate_always: activate_always)
|
27
27
|
@id = id
|
28
28
|
@block = block
|
29
|
-
@values =
|
29
|
+
@values = fields.take(values.size).zip(values).to_h.freeze
|
30
30
|
@fields = (fields - @values.keys).freeze
|
31
31
|
end
|
32
32
|
|
@@ -34,7 +34,7 @@ module Rubanok
|
|
34
34
|
values.all? { |key, matcher| params.key?(key) && (matcher == params[key]) }
|
35
35
|
end
|
36
36
|
|
37
|
-
|
37
|
+
alias_method :to_method_name, :id
|
38
38
|
end
|
39
39
|
|
40
40
|
attr_reader :clauses
|
@@ -73,7 +73,7 @@ module Rubanok
|
|
73
73
|
rule.instance_eval(&block)
|
74
74
|
|
75
75
|
define_method(rule.to_method_name) do |params = {}|
|
76
|
-
params ||= {}
|
76
|
+
params ||= {}
|
77
77
|
|
78
78
|
clause = rule.matching_clause(params)
|
79
79
|
|
@@ -92,10 +92,6 @@ module Rubanok
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
def self.included(base)
|
96
|
-
base.extend ClassMethods
|
97
|
-
end
|
98
|
-
|
99
95
|
def default_match_handler(rule, params, fail_when_no_matches)
|
100
96
|
fail_when_no_matches = Rubanok.fail_when_no_matches if fail_when_no_matches.nil?
|
101
97
|
return raw unless fail_when_no_matches
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rubanok
|
4
|
+
module DSL
|
5
|
+
# Adds `.process` method to Processor to define a nested processor:
|
6
|
+
#
|
7
|
+
# process :filter do
|
8
|
+
# map :status do |status:|
|
9
|
+
# raw.where(status:)
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
module Process
|
13
|
+
class Rule < Rubanok::Rule
|
14
|
+
METHOD_PREFIX = "__process"
|
15
|
+
|
16
|
+
def initialize(...)
|
17
|
+
super
|
18
|
+
raise ArgumentError, "Nested processor requires exactly one field" if fields.size != 1
|
19
|
+
@field = fields.first
|
20
|
+
end
|
21
|
+
|
22
|
+
def define_processor(superclass, &block)
|
23
|
+
@processor = Class.new(superclass, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def process(input, params)
|
27
|
+
return input if params.nil?
|
28
|
+
|
29
|
+
subparams = fetch_value(params, field)
|
30
|
+
return input if subparams == UNDEFINED
|
31
|
+
|
32
|
+
return input unless subparams.respond_to?(:transform_keys)
|
33
|
+
|
34
|
+
# @type var subparams : params
|
35
|
+
processor.call(input, subparams)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
attr_reader :processor, :field
|
41
|
+
|
42
|
+
def build_method_name
|
43
|
+
"#{METHOD_PREFIX}#{super}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
module ClassMethods
|
48
|
+
def process(field, superclass: ::Rubanok::Processor, activate_on: [field], activate_always: false, ignore_empty_values: Rubanok.ignore_empty_values, filter_with: nil, &block)
|
49
|
+
filter = filter_with
|
50
|
+
|
51
|
+
if filter.is_a?(Symbol)
|
52
|
+
respond_to?(filter) || raise(
|
53
|
+
ArgumentError,
|
54
|
+
"Unknown class method #{filter} for #{self}. " \
|
55
|
+
"Make sure that a filter method is defined before the call to .map."
|
56
|
+
)
|
57
|
+
filter = method(filter)
|
58
|
+
end
|
59
|
+
|
60
|
+
rule = Rule.new([field], activate_on: activate_on, activate_always: activate_always, ignore_empty_values: ignore_empty_values, filter_with: filter)
|
61
|
+
rule.define_processor(superclass, &block)
|
62
|
+
|
63
|
+
define_method(rule.to_method_name) do |params = {}|
|
64
|
+
rule.process(raw, params)
|
65
|
+
end
|
66
|
+
|
67
|
+
add_rule rule
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/rubanok/processor.rb
CHANGED
@@ -6,6 +6,7 @@ require "rubanok/rule"
|
|
6
6
|
|
7
7
|
require "rubanok/dsl/mapping"
|
8
8
|
require "rubanok/dsl/matching"
|
9
|
+
require "rubanok/dsl/process"
|
9
10
|
|
10
11
|
module Rubanok
|
11
12
|
# Base class for processors (_planes_)
|
@@ -29,8 +30,12 @@ module Rubanok
|
|
29
30
|
#
|
30
31
|
# You can access the input data via `raw` method.
|
31
32
|
class Processor
|
33
|
+
extend DSL::Matching::ClassMethods
|
32
34
|
include DSL::Matching
|
35
|
+
extend DSL::Mapping::ClassMethods
|
33
36
|
include DSL::Mapping
|
37
|
+
extend DSL::Process::ClassMethods
|
38
|
+
include DSL::Process
|
34
39
|
|
35
40
|
UNDEFINED = Object.new
|
36
41
|
|
@@ -106,8 +111,8 @@ module Rubanok
|
|
106
111
|
|
107
112
|
attr_accessor :input, :prepared
|
108
113
|
|
109
|
-
|
110
|
-
|
114
|
+
alias_method :raw, :input
|
115
|
+
alias_method :prepared?, :prepared
|
111
116
|
|
112
117
|
def apply_rule!(rule, params)
|
113
118
|
method_name, data = rule.to_method_name, rule.project(params)
|
data/lib/rubanok/version.rb
CHANGED
data/sig/rubanok/dsl/mapping.rbs
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Rubanok
|
2
2
|
module DSL
|
3
|
-
module Mapping :
|
3
|
+
module Mapping : _Processor
|
4
4
|
class Rule < Rubanok::Rule
|
5
5
|
METHOD_PREFIX: String
|
6
6
|
|
@@ -11,8 +11,6 @@ module Rubanok
|
|
11
11
|
module ClassMethods : Module, _RulesAdding
|
12
12
|
def map: (*field fields, ?activate_on: (field | Array[field]), ?activate_always: bool, ?ignore_empty_values: bool, ?filter_with: Symbol) { () -> input } -> void
|
13
13
|
end
|
14
|
-
|
15
|
-
def self.included: (singleton(Processor) base) -> void
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -3,7 +3,7 @@ module Rubanok
|
|
3
3
|
end
|
4
4
|
|
5
5
|
module DSL
|
6
|
-
module Matching :
|
6
|
+
module Matching : _Processor
|
7
7
|
class Rule < Rubanok::Rule
|
8
8
|
METHOD_PREFIX: String
|
9
9
|
@method_name: String
|
@@ -32,13 +32,12 @@ module Rubanok
|
|
32
32
|
def build_method_name: () -> String
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
def default_match_handler: (Rule rule, hash params, bool? fail_when_no_matches) -> void
|
36
|
+
|
37
|
+
module ClassMethods : Module, _RulesAdding
|
36
38
|
def match: (*field fields, ?activate_on: field | Array[field], ?activate_always: bool, ?fail_when_no_matches: bool?) { (Rule) -> void } -> void
|
39
|
+
def define_method: (String | Symbol) ?{ () [self: Rubanok::Processor] -> void } -> Symbol
|
37
40
|
end
|
38
|
-
|
39
|
-
def self.included: (singleton(Processor) base) -> void
|
40
|
-
|
41
|
-
def default_match_handler: (Rule rule, hash params, bool? fail_when_no_matches) -> void
|
42
41
|
end
|
43
42
|
end
|
44
43
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Rubanok
|
2
|
+
module DSL
|
3
|
+
module Process : _Processor
|
4
|
+
class Rule < Rubanok::Rule
|
5
|
+
METHOD_PREFIX: String
|
6
|
+
|
7
|
+
attr_reader field: field
|
8
|
+
attr_reader processor: singleton(Processor)
|
9
|
+
|
10
|
+
%a{rbs:test:skip} def define_processor: (singleton(Processor)) { () -> void } -> void
|
11
|
+
def process: (input, params | nil) -> input
|
12
|
+
|
13
|
+
private
|
14
|
+
def build_method_name: () -> String
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods : Module, _RulesAdding
|
18
|
+
%a{rbs:test:skip} def process: (field, superclass: singleton(Processor), ?activate_on: (field | Array[field]), ?activate_always: bool, ?ignore_empty_values: bool, ?filter_with: Symbol) { () -> input } -> void
|
19
|
+
def define_method: (String | Symbol) ?{ () [self: Rubanok::Processor] -> void } -> Symbol
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/sig/rubanok/processor.rbs
CHANGED
@@ -11,11 +11,20 @@ module Rubanok
|
|
11
11
|
def add_rule: (Rule rule) -> void
|
12
12
|
end
|
13
13
|
|
14
|
+
interface _Processor
|
15
|
+
def raw: () -> input
|
16
|
+
end
|
17
|
+
|
14
18
|
class Processor
|
19
|
+
include DSL::Matching
|
15
20
|
extend DSL::Matching::ClassMethods
|
16
21
|
|
22
|
+
include DSL::Mapping
|
17
23
|
extend DSL::Mapping::ClassMethods
|
18
24
|
|
25
|
+
include DSL::Process
|
26
|
+
extend DSL::Process::ClassMethods
|
27
|
+
|
19
28
|
extend _RulesAdding
|
20
29
|
|
21
30
|
UNDEFINED: Object
|
data/sig/typeprof.rb
CHANGED
@@ -10,6 +10,16 @@ processor = Class.new(Rubanok::Processor) do
|
|
10
10
|
raw
|
11
11
|
end
|
12
12
|
|
13
|
+
process :filter do
|
14
|
+
map :status do |status:|
|
15
|
+
raw
|
16
|
+
end
|
17
|
+
|
18
|
+
map :name do |name:|
|
19
|
+
raw
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
13
23
|
match :sort_by, :sort, activate_on: :sort_by do
|
14
24
|
having "status", "asc" do
|
15
25
|
raw
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubanok
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Dementyev
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '6.0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '6.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: actionview
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '6.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '6.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,6 +107,7 @@ files:
|
|
107
107
|
- lib/rubanok.rb
|
108
108
|
- lib/rubanok/dsl/mapping.rb
|
109
109
|
- lib/rubanok/dsl/matching.rb
|
110
|
+
- lib/rubanok/dsl/process.rb
|
110
111
|
- lib/rubanok/processor.rb
|
111
112
|
- lib/rubanok/rails/controller.rb
|
112
113
|
- lib/rubanok/railtie.rb
|
@@ -116,6 +117,7 @@ files:
|
|
116
117
|
- sig/rubanok.rbs
|
117
118
|
- sig/rubanok/dsl/mapping.rbs
|
118
119
|
- sig/rubanok/dsl/matching.rbs
|
120
|
+
- sig/rubanok/dsl/process.rbs
|
119
121
|
- sig/rubanok/processor.rbs
|
120
122
|
- sig/rubanok/rule.rbs
|
121
123
|
- sig/rubanok/version.rbs
|
@@ -129,7 +131,7 @@ metadata:
|
|
129
131
|
documentation_uri: http://github.com/palkan/rubanok
|
130
132
|
homepage_uri: http://github.com/palkan/rubanok
|
131
133
|
source_code_uri: http://github.com/palkan/rubanok
|
132
|
-
post_install_message:
|
134
|
+
post_install_message:
|
133
135
|
rdoc_options: []
|
134
136
|
require_paths:
|
135
137
|
- lib
|
@@ -137,15 +139,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
139
|
requirements:
|
138
140
|
- - ">="
|
139
141
|
- !ruby/object:Gem::Version
|
140
|
-
version: 2.
|
142
|
+
version: 2.7.0
|
141
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
144
|
requirements:
|
143
145
|
- - ">="
|
144
146
|
- !ruby/object:Gem::Version
|
145
147
|
version: '0'
|
146
148
|
requirements: []
|
147
|
-
rubygems_version: 3.
|
148
|
-
signing_key:
|
149
|
+
rubygems_version: 3.4.20
|
150
|
+
signing_key:
|
149
151
|
specification_version: 4
|
150
152
|
summary: Parameters-based transformation DSL
|
151
153
|
test_files: []
|