Guest User

Untitled

a guest
Feb 16th, 2019
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.81 KB | None | 0 0
  1. # This creates a nice chainable command pattern which is very powerful
  2. # when pulling business logic out of controllers or models, and allows
  3. # for observers and notifications to be easily added.
  4.  
  5. module RJ
  6. module Utils
  7. module Commands
  8. class Base
  9. include Errors
  10. include Notifications
  11. include NullListener
  12. include OptionsHash
  13.  
  14. class << self
  15. attr_reader :default_failure_callback, :default_success_callback
  16.  
  17. def call(inputs={}, **args)
  18. new(inputs, **args).call
  19. rescue NoMethodError => e
  20. raise Errors::InvalidCommandInputs.new "Invalid Input #{e.message[/`(.*?)='/m, 1]}"
  21. end
  22.  
  23. def for(inputs={}, **args)
  24. new(inputs, **args)
  25. rescue NoMethodError => e
  26. raise Errors::InvalidCommandInputs.new "Invalid Input #{e.message[/`(.*?)='/m, 1]}"
  27. end
  28.  
  29. def default_callbacks(**args)
  30. @default_success_callback = args[:on_success]
  31. @default_failure_callback = args[:on_failure]
  32. end
  33.  
  34. def optional(*input_names)
  35. input_names.each do |input_name|
  36. optional_inputs << input_name
  37. attr_accessor input_name
  38. end
  39. end
  40.  
  41. def optional_inputs
  42. @optional_inputs ||= Set.new
  43. end
  44.  
  45. def required(*input_names)
  46. input_names.each do |input_name|
  47. required_inputs << input_name
  48. attr_accessor input_name
  49. end
  50. end
  51.  
  52. def required_inputs
  53. @required_inputs ||= Set.new
  54. end
  55. end
  56.  
  57. attr_reader :listener, :on_success, :on_failure
  58.  
  59. def initialize(inputs={}, listener: nil, on_success: nil, on_failure: nil, **args)
  60. @listener = listener || null_listener
  61. @on_success = on_success || default_success_callback
  62. @on_failure = on_failure || default_failure_callback
  63.  
  64. self.inputs = recursive_symbolize_keys inputs.merge!(args)
  65.  
  66. unless valid_command_inputs?
  67. raise Errors::InvalidCommandInputs.new(
  68. "Missing required inputs: '#{missing_command_inputs.join(', ')}'",
  69. )
  70. end
  71. end
  72.  
  73. def call
  74. raise NotImplementedError
  75. end
  76.  
  77. def inputs=(inputs)
  78. inputs.each { |input, value| public_send("#{input}=", value) }
  79. end
  80.  
  81. def inputs
  82. required_inputs.merge(optional_inputs)
  83. end
  84.  
  85. def optional_inputs
  86. self.class.optional_inputs.each_with_object({}) do |input, optional_inputs|
  87. optional_inputs[input] = public_send(input)
  88. end
  89. end
  90.  
  91. def required_inputs
  92. self.class.required_inputs.each_with_object({}) do |input, required_inputs|
  93. required_inputs[input] = public_send(input)
  94. end
  95. end
  96.  
  97.  
  98. private
  99.  
  100. def valid_command_inputs?
  101. self.class.required_inputs.all? { |input| !send(input).nil? }
  102. end
  103.  
  104. def missing_command_inputs
  105. self.class.required_inputs.select { |input| send(input).nil? }
  106. end
  107.  
  108. # Callbacks
  109.  
  110. def failure(*return_args)
  111. notify_observers of_event: :failure
  112. listener.public_send(on_failure, *return_args)
  113. end
  114.  
  115. def success(*return_args)
  116. notify_observers of_event: :success
  117. listener.public_send(on_success, *return_args)
  118. end
  119.  
  120.  
  121. # Default Callbacks
  122.  
  123. def default_failure_callback
  124. raise NotImplementedError unless self.class.default_failure_callback
  125.  
  126. self.class.default_failure_callback
  127. end
  128.  
  129. def default_success_callback
  130. raise NotImplementedError unless self.class.default_success_callback
  131.  
  132. self.class.default_success_callback
  133. end
  134.  
  135. end
  136. end
  137. end
  138. end
Add Comment
Please, Sign In to add comment