Module: Igniter::Extensions::Contracts::AggregatePack
- Defined in:
- lib/igniter/extensions/contracts/aggregate_pack.rb
Constant Summary collapse
- AGGREGATE_KEYWORDS =
%i[count sum avg].freeze
Class Method Summary collapse
- .avg_keyword ⇒ Object
- .count_keyword ⇒ Object
- .enumerable_source(source, source_name:, operation_name:) ⇒ Object
- .extract_value(item, projection) ⇒ Object
- .install_dsl_keywords(kernel) ⇒ Object
- .install_into(kernel) ⇒ Object
- .manifest ⇒ Object
- .sum_keyword ⇒ Object
Class Method Details
.avg_keyword ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/igniter/extensions/contracts/aggregate_pack.rb', line 65 def avg_keyword Igniter::Contracts::DslKeyword.new(:avg) do |name, from:, builder:, using: nil| builder.add_operation( kind: :compute, name: name, depends_on: [from.to_sym], callable: lambda do |**values| items = AggregatePack.enumerable_source(values.fetch(from.to_sym), source_name: from.to_sym, operation_name: :avg) projected = items.map { |item| AggregatePack.extract_value(item, using) } next nil if projected.empty? projected.sum.to_f / projected.length end ) end end |
.count_keyword ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/igniter/extensions/contracts/aggregate_pack.rb', line 28 def count_keyword Igniter::Contracts::DslKeyword.new(:count) do |name, from:, builder:, matching: nil| builder.add_operation( kind: :compute, name: name, depends_on: [from.to_sym], callable: lambda do |**values| items = AggregatePack.enumerable_source(values.fetch(from.to_sym), source_name: from.to_sym, operation_name: :count) if matching items.count { |item| matching.call(item) } else items.count end end ) end end |
.enumerable_source(source, source_name:, operation_name:) ⇒ Object
83 84 85 86 87 |
# File 'lib/igniter/extensions/contracts/aggregate_pack.rb', line 83 def enumerable_source(source, source_name:, operation_name:) return source.to_a if source.respond_to?(:to_a) raise TypeError, "#{operation_name} source #{source_name} is not enumerable" end |
.extract_value(item, projection) ⇒ Object
89 90 91 92 93 94 95 96 97 98 |
# File 'lib/igniter/extensions/contracts/aggregate_pack.rb', line 89 def extract_value(item, projection) return item if projection.nil? return projection.call(item) if projection.respond_to?(:call) key = projection.to_sym return item.fetch(key) if item.respond_to?(:key?) && item.key?(key) return item.fetch(key.to_s) if item.respond_to?(:key?) && item.key?(key.to_s) item.public_send(key) end |
.install_dsl_keywords(kernel) ⇒ Object
22 23 24 25 26 |
# File 'lib/igniter/extensions/contracts/aggregate_pack.rb', line 22 def install_dsl_keywords(kernel) kernel.dsl_keywords.register(:count, count_keyword) kernel.dsl_keywords.register(:sum, sum_keyword) kernel.dsl_keywords.register(:avg, avg_keyword) end |
.install_into(kernel) ⇒ Object
17 18 19 20 |
# File 'lib/igniter/extensions/contracts/aggregate_pack.rb', line 17 def install_into(kernel) install_dsl_keywords(kernel) kernel end |
.manifest ⇒ Object
10 11 12 13 14 15 |
# File 'lib/igniter/extensions/contracts/aggregate_pack.rb', line 10 def manifest Igniter::Contracts::PackManifest.new( name: :extensions_aggregate, registry_contracts: AGGREGATE_KEYWORDS.map { |kind| Igniter::Contracts::PackManifest.dsl_keyword(kind) } ) end |
.sum_keyword ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/igniter/extensions/contracts/aggregate_pack.rb', line 48 def sum_keyword Igniter::Contracts::DslKeyword.new(:sum) do |name, from:, builder:, using: nil| builder.add_operation( kind: :compute, name: name, depends_on: [from.to_sym], callable: lambda do |**values| items = AggregatePack.enumerable_source(values.fetch(from.to_sym), source_name: from.to_sym, operation_name: :sum) items.reduce(0) do |total, item| total + AggregatePack.extract_value(item, using) end end ) end end |