rubanok 0.1.1 → 0.4.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.
data/lib/rubanok/rule.rb CHANGED
@@ -1,23 +1,39 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubanok
4
+ using(Module.new do
5
+ refine NilClass do
6
+ def empty?
7
+ true
8
+ end
9
+ end
10
+
11
+ refine Object do
12
+ def empty?
13
+ false
14
+ end
15
+ end
16
+ end)
17
+
4
18
  class Rule # :nodoc:
5
- UNDEFINED = :__undef__
19
+ UNDEFINED = Object.new
6
20
 
7
- attr_reader :fields, :activate_on, :activate_always
21
+ attr_reader :fields, :activate_on, :activate_always, :ignore_empty_values, :filter_with
8
22
 
9
- def initialize(fields, activate_on: fields, activate_always: false)
23
+ def initialize(fields, activate_on: fields, activate_always: false, ignore_empty_values: Rubanok.ignore_empty_values, filter_with: nil)
10
24
  @fields = fields.freeze
11
- @activate_on = Array(activate_on).freeze
25
+ # @type var activate_on: Array[Symbol]
26
+ activate_on = Array(activate_on)
27
+ @activate_on = activate_on.freeze
12
28
  @activate_always = activate_always
29
+ @ignore_empty_values = ignore_empty_values
30
+ @filter_with = filter_with
13
31
  end
14
32
 
15
33
  def project(params)
16
34
  fields.each_with_object({}) do |field, acc|
17
35
  val = fetch_value params, field
18
- next acc if val == UNDEFINED
19
-
20
- acc[field] = val
36
+ acc[field] = val if val != UNDEFINED
21
37
  acc
22
38
  end
23
39
  end
@@ -25,7 +41,7 @@ module Rubanok
25
41
  def applicable?(params)
26
42
  return true if activate_always == true
27
43
 
28
- activate_on.all? { |field| params.key?(field) && !empty?(params[field]) }
44
+ activate_on.all? { |field| fetch_value(params, field) != UNDEFINED }
29
45
  end
30
46
 
31
47
  def to_method_name
@@ -39,27 +55,19 @@ module Rubanok
39
55
  end
40
56
 
41
57
  def fetch_value(params, field)
42
- return UNDEFINED if !params.key?(field) || empty?(params[field])
58
+ return UNDEFINED unless params.key?(field)
43
59
 
44
- params[field]
45
- end
60
+ val = params[field]
46
61
 
47
- using(Module.new do
48
- refine NilClass do
49
- def empty?
50
- true
51
- end
52
- end
62
+ val = filter_with&.call(val) if filter_with
53
63
 
54
- refine Object do
55
- def empty?
56
- false
57
- end
58
- end
59
- end)
64
+ return UNDEFINED if empty?(val)
65
+
66
+ val
67
+ end
60
68
 
61
69
  def empty?(val)
62
- return false unless Rubanok.ignore_empty_values
70
+ return false unless ignore_empty_values
63
71
 
64
72
  val.empty?
65
73
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubanok
4
- VERSION = "0.1.1"
4
+ VERSION = "0.4.0"
5
5
  end
data/sig/rubanok.rbs ADDED
@@ -0,0 +1,6 @@
1
+ module Rubanok
2
+ def self.fail_when_no_matches: () -> bool
3
+ def self.fail_when_no_matches=: (bool) -> bool
4
+ def self.ignore_empty_values: () -> bool
5
+ def self.ignore_empty_values=: (bool) -> bool
6
+ end
@@ -0,0 +1,18 @@
1
+ module Rubanok
2
+ module DSL
3
+ module Mapping : Processor
4
+ class Rule < Rubanok::Rule
5
+ METHOD_PREFIX: String
6
+
7
+ private
8
+ def build_method_name: () -> String
9
+ end
10
+
11
+ module ClassMethods : Module, _RulesAdding
12
+ def map: (*field fields, ?activate_on: (field | Array[field]), ?activate_always: bool, ?ignore_empty_values: bool, ?filter_with: Symbol) { () -> input } -> void
13
+ end
14
+
15
+ def self.included: (singleton(Processor) base) -> void
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,44 @@
1
+ module Rubanok
2
+ class UnexpectedInputError < StandardError
3
+ end
4
+
5
+ module DSL
6
+ module Matching : Processor
7
+ class Rule < Rubanok::Rule
8
+ METHOD_PREFIX: String
9
+ @method_name: String
10
+ @fields: Array[field]
11
+
12
+ class Clause < Rubanok::Rule
13
+ @fields: Array[field]
14
+
15
+ attr_reader values: params
16
+ attr_reader id: String
17
+ attr_reader block: ^() -> input
18
+
19
+ def initialize: (String id, Array[field] fields, untyped values, ?activate_on: field | Array[field], ?activate_always: bool) { () -> input } -> void
20
+ def applicable?: (params) -> bool
21
+
22
+ alias to_method_name id
23
+ end
24
+
25
+ attr_reader clauses: Array[Clause]
26
+
27
+ def matching_clause: (hash params) -> Clause?
28
+ def having: (*untyped values) { () -> input } -> void
29
+ def default: () { () -> input } -> void
30
+
31
+ private
32
+ def build_method_name: () -> String
33
+ end
34
+
35
+ module ClassMethods : Module, _RulesAdding, Matching
36
+ def match: (*field fields, ?activate_on: field | Array[field], ?activate_always: bool, ?fail_when_no_matches: bool?) { (Rule) -> void } -> void
37
+ 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
+ end
43
+ end
44
+ end
@@ -0,0 +1,53 @@
1
+ module Rubanok
2
+ # Transformation parameters
3
+ type params = Hash[Symbol | String, untyped]
4
+ # Untyped Hash
5
+ type hash = Hash[untyped, untyped]
6
+ type field = Symbol
7
+ # Transformation target (we assume that input and output types are the same)
8
+ type input = Object?
9
+
10
+ interface _RulesAdding
11
+ def add_rule: (Rule rule) -> void
12
+ end
13
+
14
+ class Processor
15
+ extend DSL::Matching::ClassMethods
16
+
17
+ extend DSL::Mapping::ClassMethods
18
+
19
+ extend _RulesAdding
20
+
21
+ UNDEFINED: Object
22
+
23
+ self.@rules: Array[Rule]
24
+ self.@fields_set: Set[field]
25
+
26
+ def self.superclass: () -> singleton(Processor)
27
+
28
+ def self.call: (input, params) -> input
29
+ | (params) -> input
30
+ def self.rules: () -> Array[Rule]
31
+ def self.fields_set: () -> Set[field]
32
+ def self.project: (params) -> params
33
+ def self.prepare: () { () -> input } -> void
34
+
35
+ def initialize: (input) -> void
36
+ def call: (params) -> input
37
+
38
+ attr_accessor input: input
39
+
40
+ private
41
+ attr_accessor prepared: bool
42
+
43
+ alias raw input
44
+ alias prepared? prepared
45
+
46
+ def apply_rule!: (Rule rule, params) -> void
47
+ def prepare: () -> input
48
+ def prepare!: () -> void
49
+ def rules: () -> Array[Rule]
50
+ end
51
+
52
+ Plane: singleton(Processor)
53
+ end
@@ -0,0 +1,29 @@
1
+ module Rubanok
2
+ class Rule
3
+ UNDEFINED: Object
4
+
5
+ @method_name: String
6
+
7
+ attr_reader fields: Array[field]
8
+ attr_reader activate_on: Array[field]
9
+ attr_reader activate_always: bool
10
+ attr_reader ignore_empty_values: bool
11
+ attr_reader filter_with: Method?
12
+
13
+ %a{rbs:test:skip} def initialize: (
14
+ Array[field] fields,
15
+ ?activate_on: field | Array[field],
16
+ ?activate_always: bool,
17
+ ?ignore_empty_values: bool,
18
+ ?filter_with: Method?
19
+ ) -> void
20
+ def project: (params) -> params
21
+ def applicable?: (params) -> bool
22
+ def to_method_name: () -> String
23
+
24
+ private
25
+ def build_method_name: () -> String
26
+ def fetch_value: (params, field) -> Object
27
+ def empty?: (untyped) -> bool
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module Rubanok
2
+ VERSION: String
3
+ end
data/sig/typeprof.rb ADDED
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Run typeprofiler:
4
+ #
5
+ # typeprof -Ilib sig/typeprof.rb
6
+ require "rubanok"
7
+
8
+ processor = Class.new(Rubanok::Processor) do
9
+ map :q do |q:|
10
+ raw
11
+ end
12
+
13
+ match :sort_by, :sort, activate_on: :sort_by do
14
+ having "status", "asc" do
15
+ raw
16
+ end
17
+
18
+ default do |sort_by:, sort: "asc"|
19
+ raw
20
+ end
21
+ end
22
+ end
23
+
24
+ processor.project({q: "search", sort_by: "name"})
25
+ processor.call([], {q: "search", sort_by: "name"})
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.1.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-17 00:00:00.000000000 Z
11
+ date: 2021-03-05 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: '4.2'
19
+ version: '5.2'
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: '4.2'
26
+ version: '5.2'
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: '4.2'
33
+ version: '5.2'
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: '4.2'
40
+ version: '5.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -54,62 +54,34 @@ dependencies:
54
54
  version: '1.16'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '10.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '10.0'
69
- - !ruby/object:Gem::Dependency
70
- name: rspec
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '3.0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '3.0'
83
- - !ruby/object:Gem::Dependency
84
- name: rspec-rails
85
57
  requirement: !ruby/object:Gem::Requirement
86
58
  requirements:
87
59
  - - ">="
88
60
  - !ruby/object:Gem::Version
89
- version: '0'
61
+ version: '13.0'
90
62
  type: :development
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
66
  - - ">="
95
67
  - !ruby/object:Gem::Version
96
- version: '0'
68
+ version: '13.0'
97
69
  - !ruby/object:Gem::Dependency
98
- name: rubocop-rspec
70
+ name: rspec
99
71
  requirement: !ruby/object:Gem::Requirement
100
72
  requirements:
101
73
  - - ">="
102
74
  - !ruby/object:Gem::Version
103
- version: '0'
75
+ version: '3.0'
104
76
  type: :development
105
77
  prerelease: false
106
78
  version_requirements: !ruby/object:Gem::Requirement
107
79
  requirements:
108
80
  - - ">="
109
81
  - !ruby/object:Gem::Version
110
- version: '0'
82
+ version: '3.0'
111
83
  - !ruby/object:Gem::Dependency
112
- name: standard
84
+ name: rspec-rails
113
85
  requirement: !ruby/object:Gem::Requirement
114
86
  requirements:
115
87
  - - ">="
@@ -129,36 +101,34 @@ executables: []
129
101
  extensions: []
130
102
  extra_rdoc_files: []
131
103
  files:
132
- - ".gitignore"
133
- - ".rspec"
134
- - ".rubocop.yml"
135
- - ".travis.yml"
136
104
  - CHANGELOG.md
137
- - Gemfile
138
- - Gemfile.local
139
105
  - LICENSE.txt
140
106
  - README.md
141
- - Rakefile
142
- - bin/console
143
- - bin/setup
144
- - gemfiles/rails42.gemfile
145
- - gemfiles/rails52.gemfile
146
- - gemfiles/railsmaster.gemfile
147
107
  - lib/rubanok.rb
148
108
  - lib/rubanok/dsl/mapping.rb
149
109
  - lib/rubanok/dsl/matching.rb
150
- - lib/rubanok/ext/symbolize_keys.rb
151
- - lib/rubanok/plane.rb
110
+ - lib/rubanok/processor.rb
152
111
  - lib/rubanok/rails/controller.rb
153
112
  - lib/rubanok/railtie.rb
154
113
  - lib/rubanok/rspec.rb
155
114
  - lib/rubanok/rule.rb
156
115
  - lib/rubanok/version.rb
157
- - rubanok.gemspec
116
+ - sig/rubanok.rbs
117
+ - sig/rubanok/dsl/mapping.rbs
118
+ - sig/rubanok/dsl/matching.rbs
119
+ - sig/rubanok/processor.rbs
120
+ - sig/rubanok/rule.rbs
121
+ - sig/rubanok/version.rbs
122
+ - sig/typeprof.rb
158
123
  homepage: https://github.com/palkan/rubanok
159
124
  licenses:
160
125
  - MIT
161
- metadata: {}
126
+ metadata:
127
+ bug_tracker_uri: http://github.com/palkan/rubanok/issues
128
+ changelog_uri: https://github.com/palkan/rubanok/blob/master/CHANGELOG.md
129
+ documentation_uri: http://github.com/palkan/rubanok
130
+ homepage_uri: http://github.com/palkan/rubanok
131
+ source_code_uri: http://github.com/palkan/rubanok
162
132
  post_install_message:
163
133
  rdoc_options: []
164
134
  require_paths:
@@ -174,8 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
174
144
  - !ruby/object:Gem::Version
175
145
  version: '0'
176
146
  requirements: []
177
- rubyforge_project:
178
- rubygems_version: 2.7.6
147
+ rubygems_version: 3.0.6
179
148
  signing_key:
180
149
  specification_version: 4
181
150
  summary: Parameters-based transformation DSL