PromiseHash

Christopher Vollick created

Here in info I'm doing a lot of this pattern:

    EMPromise.all([one, two three]).then { |one, two, three|
    	new(one: one, two: two, three: three)
    }

Which felt really noisy for what is a pretty logical operation.
So now I can keep the keys and values together and do:

    PromiseHash.all(one: one, two: two, three:three).then(&method(:new))

It's smaller, but more importantly it's more meaningful to me.
It keeps the declaration of the meaning together with the sourcing of
the value.
And because it uses EMPromise.all in the guts it's not a problem if some
of the keys are not promises.
Easy-peasy!

Change summary

lib/customer_info.rb | 32 ++++++++++++++------------------
lib/promise_hash.rb  | 12 ++++++++++++
2 files changed, 26 insertions(+), 18 deletions(-)

Detailed changes

lib/customer_info.rb 🔗

@@ -7,6 +7,7 @@ require "value_semantics/monkey_patched"
 require_relative "proxied_jid"
 require_relative "customer_plan"
 require_relative "form_template"
+require_relative "promise_hash"
 
 class PlanInfo
 	extend Forwardable
@@ -78,14 +79,12 @@ class CustomerInfo
 	end
 
 	def self.for(customer, plan)
-		PlanInfo.for(plan).then do |plan_info|
-			new(
-				plan_info: plan_info,
-				tel: customer.registered? ? customer.registered?.phone : nil,
-				balance: customer.balance,
-				cnam: customer.tndetails.dig(:features, :lidb, :subscriber_information)
-			)
-		end
+		PromiseHash.all(
+			plan_info: PlanInfo.for(plan),
+			tel: customer.registered? ? customer.registered?.phone : nil,
+			balance: customer.balance,
+			cnam: customer.tndetails.dig(:features, :lidb, :subscriber_information)
+		).then(&method(:new))
 	end
 
 	def form
@@ -103,16 +102,13 @@ class AdminInfo
 	end
 
 	def self.for(customer, plan)
-		EMPromise.all([
-			CustomerInfo.for(customer, plan),
-			customer.api
-		]).then do |info, api_value|
-			new(
-				jid: customer.jid,
-				customer_id: customer.customer_id,
-				fwd: customer.fwd, info: info, api: api_value
-			)
-		end
+		PromiseHash.all(
+			jid: customer.jid,
+			customer_id: customer.customer_id,
+			fwd: customer.fwd,
+			info: CustomerInfo.for(customer, plan),
+			api: customer.api
+		).then(&method(:new))
 	end
 
 	def form

lib/promise_hash.rb 🔗

@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require "em_promise"
+
+module PromiseHash
+	def self.all(**kwargs)
+		keys = kwargs.keys
+		EMPromise.all(kwargs.values).then { |results|
+			Hash[keys.zip(results)]
+		}
+	end
+end