rubanok 0.1.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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