evil_events 0.1.0rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +84 -0
  5. data/.travis.yml +10 -0
  6. data/.yardopts +1 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +6 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +17 -0
  11. data/Rakefile +6 -0
  12. data/bin/console +12 -0
  13. data/bin/setup +8 -0
  14. data/evil_events.gemspec +42 -0
  15. data/lib/evil_events/boot_point.rb +17 -0
  16. data/lib/evil_events/config.rb +30 -0
  17. data/lib/evil_events/core/activity_logging.rb +24 -0
  18. data/lib/evil_events/core/broadcasting/adapters/memory_async.rb +20 -0
  19. data/lib/evil_events/core/broadcasting/adapters/memory_sync.rb +20 -0
  20. data/lib/evil_events/core/broadcasting/adapters.rb +11 -0
  21. data/lib/evil_events/core/broadcasting/dispatcher/dispatchable.rb +17 -0
  22. data/lib/evil_events/core/broadcasting/dispatcher.rb +17 -0
  23. data/lib/evil_events/core/broadcasting/emitter.rb +45 -0
  24. data/lib/evil_events/core/broadcasting.rb +13 -0
  25. data/lib/evil_events/core/events/abstract_event.rb +44 -0
  26. data/lib/evil_events/core/events/event_class_factory.rb +54 -0
  27. data/lib/evil_events/core/events/event_extensions/adapter_customizable.rb +49 -0
  28. data/lib/evil_events/core/events/event_extensions/manageable.rb +26 -0
  29. data/lib/evil_events/core/events/event_extensions/observable.rb +49 -0
  30. data/lib/evil_events/core/events/event_extensions/payloadable/abstract_payload.rb +24 -0
  31. data/lib/evil_events/core/events/event_extensions/payloadable.rb +52 -0
  32. data/lib/evil_events/core/events/event_extensions/serializable.rb +21 -0
  33. data/lib/evil_events/core/events/event_extensions/type_aliasing.rb +87 -0
  34. data/lib/evil_events/core/events/manager/subscriber_list.rb +30 -0
  35. data/lib/evil_events/core/events/manager.rb +78 -0
  36. data/lib/evil_events/core/events/manager_factory.rb +17 -0
  37. data/lib/evil_events/core/events/manager_registry.rb +141 -0
  38. data/lib/evil_events/core/events/serializers/hash.rb +51 -0
  39. data/lib/evil_events/core/events/serializers/json.rb +43 -0
  40. data/lib/evil_events/core/events/serializers.rb +16 -0
  41. data/lib/evil_events/core/events/subscriber/mixin.rb +28 -0
  42. data/lib/evil_events/core/events/subscriber.rb +43 -0
  43. data/lib/evil_events/core/events.rb +25 -0
  44. data/lib/evil_events/core.rb +10 -0
  45. data/lib/evil_events/shared/combined_context.rb +113 -0
  46. data/lib/evil_events/shared/combined_context_mixin.rb +43 -0
  47. data/lib/evil_events/shared/configurable.rb +7 -0
  48. data/lib/evil_events/shared/delegator_resolver.rb +36 -0
  49. data/lib/evil_events/shared/dependency_container.rb +7 -0
  50. data/lib/evil_events/shared/logger.rb +13 -0
  51. data/lib/evil_events/shared/mockable_class_builder.rb +27 -0
  52. data/lib/evil_events/shared/structure.rb +7 -0
  53. data/lib/evil_events/shared/types.rb +9 -0
  54. data/lib/evil_events/shared.rb +16 -0
  55. data/lib/evil_events/system/mock.rb +70 -0
  56. data/lib/evil_events/system.rb +149 -0
  57. data/lib/evil_events/version.rb +7 -0
  58. data/lib/evil_events.rb +53 -0
  59. metadata +269 -0
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events::EventExtensions
4
+ # @api private
5
+ # @since 0.1.0
6
+ module AdapterCustomizable
7
+ class << self
8
+ # @param base_class [Class]
9
+ #
10
+ # @since 0.1.0
11
+ def included(base_class)
12
+ base_class.extend(ClassMethods)
13
+ end
14
+ end
15
+
16
+ # @return [EvilEvents::Core::Broadcasting::Dispatcher::Dispatchable]
17
+ #
18
+ # @since 0.1.0
19
+ def adapter
20
+ self.class.adapter
21
+ end
22
+
23
+ # @return [EvilEvents::Core::Broadcasting::Dispatcher::Dispatchable]
24
+ #
25
+ # @since 0.1.0
26
+ def adapter_name
27
+ self.class.adapter_name
28
+ end
29
+
30
+ # @since 0.1.0
31
+ module ClassMethods
32
+ # @param identifier [Symbol, String]
33
+ # @return [EvilEvents::Core::Broadcasting::Dispatcher::Dispatchable]
34
+ #
35
+ # @since 0.1.0
36
+ def adapter(identifier = nil)
37
+ @adapter_identifier = identifier if identifier
38
+ EvilEvents::BootPoint::System[:event_system].resolve_adapter(adapter_name)
39
+ end
40
+
41
+ # @return [Symbol, String]
42
+ #
43
+ # @since 0.1.0
44
+ def adapter_name
45
+ @adapter_identifier || EvilEvents::BootPoint::System[:config].adapter.default
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events::EventExtensions
4
+ # @api private
5
+ # @since 0.1.0
6
+ module Manageable
7
+ class << self
8
+ # @param base_class [Class]
9
+ #
10
+ # @since 0.1.0
11
+ def included(base_class)
12
+ base_class.extend(ClassMethods)
13
+ end
14
+ end
15
+
16
+ # @since 0.1.0
17
+ module ClassMethods
18
+ # @return void
19
+ #
20
+ # @since 0.1.0
21
+ def manage!
22
+ EvilEvents::BootPoint::System[:event_system].register_event_class(self)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events::EventExtensions
4
+ # @api private
5
+ # @since 0.1.0
6
+ module Observable
7
+ class << self
8
+ # @param base_class [Class]
9
+ #
10
+ # @since 0.1.0
11
+ def included(base_class)
12
+ base_class.extend(ClassMethods)
13
+ end
14
+ end
15
+
16
+ # @return [Array<EvilEvents::Core::Events::Subscriber>]
17
+ #
18
+ # @since 0.1.0
19
+ def observers
20
+ self.class.observers
21
+ end
22
+
23
+ # @since 0.1.0
24
+ module ClassMethods
25
+ # @param raw_subscriber [Object]
26
+ # @param delegator [Symbol, String, NilClass]
27
+ #
28
+ # @since 0.1.0
29
+ def observe(raw_subscriber, delegator: nil)
30
+ EvilEvents::BootPoint::System[:event_system].observe(self, raw_subscriber, delegator)
31
+ end
32
+
33
+ # @param delegator [Symbol, String, NilClass]
34
+ #
35
+ # @since 0.1.0
36
+ def default_delegator(delegator = nil)
37
+ @default_delegator = delegator if delegator
38
+ @default_delegator || EvilEvents::BootPoint::System[:config].subscriber.default_delegator
39
+ end
40
+
41
+ # @return [Array]
42
+ #
43
+ # @since 0.1.0
44
+ def observers
45
+ EvilEvents::BootPoint::System[:event_system].observers(self)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events::EventExtensions::Payloadable
4
+ # @abstract
5
+ # @api private
6
+ # @since 0.1.0
7
+ class AbstractPayload < EvilEvents::Shared::Structure
8
+ class << self
9
+ # @since 0.1.0
10
+ alias_method :_native_attribute, :attribute
11
+
12
+ # @param key [Symbol]
13
+ # @param type [EvilEvents::Shared::Types::Any]
14
+ #
15
+ # @since 0.1.0
16
+ def attribute(key, type = EvilEvents::Types::Any)
17
+ _native_attribute(key, type)
18
+ end
19
+ end
20
+
21
+ # NOTE: dry-struct API + dry-initializer API
22
+ constructor_type :strict_with_defaults
23
+ end
24
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events::EventExtensions
4
+ # @api private
5
+ # @since 0.1.0
6
+ module Payloadable
7
+ class << self
8
+ # @param base_class [Class]
9
+ #
10
+ # @since 0.1.0
11
+ def included(base_class)
12
+ base_class.extend(ClassMethods)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ # @return [AbstractPayload]
19
+ #
20
+ # @since 0.1.0
21
+ def payload_class
22
+ self.class.const_get(:Payload)
23
+ end
24
+
25
+ # @since 0.1.0
26
+ module ClassMethods
27
+ # @param child_class [Class]
28
+ #
29
+ # @since 0.1.0
30
+ def inherited(child_class)
31
+ child_class.const_set(:Payload, Class.new(AbstractPayload))
32
+ super
33
+ end
34
+
35
+ # @param key [Symbol]
36
+ # @param type [EvilEvents::Shared::Types::Any]
37
+ # @return void
38
+ #
39
+ # @since 0.1.0
40
+ def attribute(key, type = EvilEvents::Shared::Types::Any)
41
+ const_get(:Payload).attribute(key, type)
42
+ end
43
+
44
+ # @return [Array<Symbol>]
45
+ #
46
+ # @since 0.1.0
47
+ def attribute_names
48
+ const_get(:Payload).attribute_names
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events::EventExtensions
4
+ # @api private
5
+ # @since 0.1.0
6
+ module Serializable
7
+ # @return [Hash]
8
+ #
9
+ # @since 0.1.0
10
+ def serialize_to_hash
11
+ EvilEvents::Core::Events::Serializers[:hash].serialize(self)
12
+ end
13
+
14
+ # @return [String]
15
+ #
16
+ # @since 0.1.0
17
+ def serialize_to_json
18
+ EvilEvents::Core::Events::Serializers[:json].serialize(self)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events::EventExtensions
4
+ # @api private
5
+ # @since 0.1.0
6
+ module TypeAliasing
7
+ # @since 0.1.0
8
+ TypeAliasingError = Class.new(StandardError)
9
+ # @since 0.1.0
10
+ IncopatibleEventTypeError = Class.new(TypeAliasingError)
11
+ # @since 0.1.0
12
+ EventTypeNotDefinedError = Class.new(TypeAliasingError)
13
+ # @since 0.1.0
14
+ EventTypeAlreadyDefinedError = Class.new(TypeAliasingError)
15
+
16
+ class << self
17
+ # @param base_class [Class]
18
+ #
19
+ # @since 0.1.0
20
+ def included(base_class)
21
+ base_class.extend(ClassMethods)
22
+ end
23
+ end
24
+
25
+ # @return [String]
26
+ #
27
+ # @since 0.1.0
28
+ def type
29
+ self.class.type
30
+ end
31
+
32
+ module ClassMethods
33
+ # @param type_alias [String, NilClass]
34
+ # @return [String]
35
+ #
36
+ # @since 0.1.0
37
+ def type(type_alias = nil)
38
+ case
39
+ when incompatible_type_alias_type?(type_alias)
40
+ raise IncopatibleEventTypeError
41
+ when fetching_type_alias_when_type_alias_not_defined?(type_alias)
42
+ raise EventTypeNotDefinedError
43
+ when providing_type_alias_when_type_alias_already_defined?(type_alias)
44
+ raise EventTypeAlreadyDefinedError
45
+ when tries_to_define_type_alias_first_time?(type_alias)
46
+ @type = type_alias
47
+ end
48
+
49
+ @type
50
+ end
51
+
52
+ private
53
+
54
+ # @param type_alias [String, NilClass]
55
+ # @return [Boolean]
56
+ #
57
+ # @since 0.1.0
58
+ def incompatible_type_alias_type?(type_alias)
59
+ !(type_alias.is_a?(NilClass) || type_alias.is_a?(String))
60
+ end
61
+
62
+ # @param type_alias [String, NilClass]
63
+ # @return [Boolean]
64
+ #
65
+ # @since 0.1.0
66
+ def fetching_type_alias_when_type_alias_not_defined?(type_alias)
67
+ !instance_variable_defined?(:@type) && type_alias.nil?
68
+ end
69
+
70
+ # @param type_alias [String, NilClass]
71
+ # @return [Boolean]
72
+ #
73
+ # @since 0.1.0
74
+ def providing_type_alias_when_type_alias_already_defined?(type_alias)
75
+ instance_variable_defined?(:@type) && type_alias
76
+ end
77
+
78
+ # @param type_alias [String, NilClass]
79
+ # @return [Boolean]
80
+ #
81
+ # @since 0.1.0
82
+ def tries_to_define_type_alias_first_time?(type_alias)
83
+ !instance_variable_defined?(:@type) && type_alias
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EvilEvents::Core::Events::Manager
4
+ # @api private
5
+ # @since 0.1.0
6
+ class SubscriberList < Concurrent::Array
7
+ # @param source_subscriber [Object]
8
+ # @return [Boolean]
9
+ #
10
+ # @since 0.1.0
11
+ def registered?(source_subscriber)
12
+ any? { |subscriber| subscriber.source_object == source_subscriber }
13
+ end
14
+
15
+ # @param source_subscriber [Object]
16
+ # @return [EvilEvents::Core::Events::Subscriber]
17
+ #
18
+ # @since 0.1.0
19
+ def wrapper_of(source_subscriber)
20
+ find { |subscriber| subscriber.source_object == source_subscriber }
21
+ end
22
+
23
+ # @return [Array<Object>]
24
+ #
25
+ # @since 0.1.0
26
+ def sources
27
+ map(&:source_object)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events
4
+ # @api private
5
+ # @since 0.1.0
6
+ class Manager
7
+ # @since 0.1.0
8
+ ManagerError = Class.new(StandardError)
9
+ # @since 0.1.0
10
+ InconsistentEventClassError = Class.new(ManagerError)
11
+ # @since 0.1.0
12
+ InvalidDelegatorTypeError = Class.new(ManagerError)
13
+
14
+ # @return [EvilEvents::Core::Events::AbstractEvent]
15
+ #
16
+ # @since 0.1.0
17
+ attr_reader :event_class
18
+
19
+ # @return [Concurrent::Array<EvilEvents::Core::Events::Subscriber>]
20
+ #
21
+ # @since 0.1.0
22
+ attr_reader :subscribers
23
+
24
+ # @param event_class [Class{EvilEvents::Core::Events::AbstractEvent}]
25
+ #
26
+ # @since 0.1.0
27
+ def initialize(event_class)
28
+ @event_class = event_class
29
+ @subscribers = SubscriberList.new
30
+ end
31
+
32
+ # @param raw_subscriber [Object]
33
+ # @param delegator [Symbol, String, NilClass]
34
+ # @raise [InvalidDelegatorTypeError]
35
+ # @return void
36
+ #
37
+ # @since 0.1.0
38
+ def observe(raw_subscriber, delegator = nil)
39
+ case delegator
40
+ when NilClass, Symbol, String # TODO: think about Dry::Types checker
41
+ subscribers.push(create_event_subscriber(raw_subscriber, delegator))
42
+ else
43
+ raise InvalidDelegatorTypeError
44
+ end
45
+ end
46
+
47
+ # @param event [EvilEvents::Core::Events::AbstractEvent]
48
+ # @raise [InconsistentEventClassError]
49
+ # @return void
50
+ #
51
+ # @since 0.1.0
52
+ def notify(event)
53
+ raise InconsistentEventClassError unless event.is_a?(event_class)
54
+ # TODO: separate notification logic to worker/jobs
55
+ subscribers.each { |subscriber| subscriber.notify(event) }
56
+ end
57
+
58
+ # @return [String, Symbol]
59
+ #
60
+ # @since 0.1.0
61
+ def event_type
62
+ event_class.type
63
+ end
64
+
65
+ private
66
+
67
+ # @param raw_subscriber [Object]
68
+ # @param delegator [Symbol, String, NilClass]
69
+ # @return [EvilEvents::Core::Events::Subscriber]
70
+ #
71
+ # @since 0.1.0
72
+ def create_event_subscriber(raw_subscriber, delegator)
73
+ delegation = -> { delegator || event_class.default_delegator }
74
+ resolver = EvilEvents::Shared::DelegatorResolver.new(delegation)
75
+ EvilEvents::Core::Events::Subscriber.new(raw_subscriber, resolver)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events
4
+ # @api private
5
+ # @since 0.1.0
6
+ module ManagerFactory
7
+ class << self
8
+ # @param event_class [Class{EvilEvents::Core::Events::AbstractEvent}]
9
+ # @return [EvilEvents::Core::Events::Manager]
10
+ #
11
+ # @since 0.1.0
12
+ def create(event_class)
13
+ Manager.new(event_class)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events
4
+ # @api private
5
+ # @since 0.1.0
6
+ class ManagerRegistry
7
+ # @since 0.1.0
8
+ extend Forwardable
9
+
10
+ # @since 0.1.0
11
+ ManagerRegistryError = Class.new(StandardError)
12
+ # @since 0.1.0
13
+ IncorrectManagerObjectError = Class.new(ManagerRegistryError)
14
+ # @since 0.1.0
15
+ NonManagedEventClassError = Class.new(ManagerRegistryError)
16
+ # @since 0.1.0
17
+ AlreadyManagedEventClassError = Class.new(ManagerRegistryError)
18
+
19
+ def_delegators :managers, :empty?, :size
20
+
21
+ # @return [Concurrent::Map]
22
+ #
23
+ # @since 0.1.0
24
+ attr_reader :managers
25
+
26
+ # @since 0.1.0
27
+ def initialize
28
+ @managers = Concurrent::Map.new
29
+ end
30
+
31
+ # @param event_class [Class{EvilEvents::Core::Events::AbstractEvent}]
32
+ # @raise [NonManagedEventClassError]
33
+ # @return [EvilEvents::Core::Events::Manager]
34
+ #
35
+ # @since 0.1.0
36
+ def manager_of_event(event_class)
37
+ # NOTE: raise exceptions to simplify runtime problems resolving
38
+ managers[event_class] || (raise NonManagedEventClassError)
39
+ end
40
+
41
+ # @param event_type [String]
42
+ # @return [EvilEvents::Core::Events::Manager]
43
+ # @see manager_of_event
44
+ #
45
+ # @since 0.1.0
46
+ def manager_of_event_type(event_type)
47
+ event_class = managed_events.find { |managed_event| managed_event.type == event_type }
48
+ manager_of_event(event_class)
49
+ end
50
+
51
+ # @param manager [EvilEvents::Core::Events::Manager]
52
+ # @raise [IncorrectManagerObjectError]
53
+ # @raise [AlreadyManagedEventClassError]
54
+ # @return void
55
+ #
56
+ # @since 0.1.0
57
+ def register(manager)
58
+ raise IncorrectManagerObjectError unless manager.is_a?(EvilEvents::Core::Events::Manager)
59
+
60
+ if potential_manager_duplicate?(manager) || !managed_event_type?(manager.event_type)
61
+ managers[manager.event_class] = manager
62
+ else
63
+ raise AlreadyManagedEventClassError
64
+ end
65
+ end
66
+
67
+ # @param event_class [Class{EvilEvents::Core::Events::AbstractEvent}]
68
+ # @return void
69
+ # @see register
70
+ #
71
+ # @since 0.1.0
72
+ def register_with(event_class)
73
+ register(ManagerFactory.create(event_class))
74
+ end
75
+
76
+ # @param manager [EvilEvents::Core::Events::Manager]
77
+ # @return void
78
+ #
79
+ # @since 0.1.0
80
+ def unregister(manager)
81
+ managers.delete_pair(manager.event_class, manager)
82
+ end
83
+
84
+ # @param event_class [Class{EvilEvents::Core::Events::AbstractEvent}]
85
+ # @return void
86
+ #
87
+ # @since 0.1.0
88
+ def unregister_with(event_class)
89
+ managers.delete(event_class)
90
+ end
91
+
92
+ # @param manager [EvilEvents::Core::Events::Manager]
93
+ # @return [Boolean]
94
+ #
95
+ # @since 0.1.0
96
+ def include?(manager)
97
+ managed_event?(manager.event_class) && manager_of_event(manager.event_class) == manager
98
+ end
99
+
100
+ # @param event_class [Class{EvilEvents::Core::Events::AbstractEvent}]
101
+ # @return [Boolean]
102
+ #
103
+ # @since 0.1.0
104
+ def managed_event?(event_class)
105
+ managers.key?(event_class)
106
+ end
107
+
108
+ private
109
+
110
+ # @return [Array<EvilEvents::Core::Events::AbstractEvent>]
111
+ #
112
+ # @since 0.1.0
113
+ def managed_events
114
+ managers.keys
115
+ end
116
+
117
+ # @return [Array<String>]
118
+ #
119
+ # @since 0.1.0
120
+ def managed_event_types
121
+ managed_events.map(&:type)
122
+ end
123
+
124
+ # @param event_type [String]
125
+ # @return [Boolean]
126
+ #
127
+ # @since 0.1.0
128
+ def managed_event_type?(event_type)
129
+ managed_event_types.include?(event_type)
130
+ end
131
+
132
+ # @param manager [EvilEvents::Core::Events::Manager]
133
+ # @return [Boolean]
134
+ #
135
+ # @since 0.1.0
136
+ def potential_manager_duplicate?(manager)
137
+ return false unless managed_event?(manager.event_class)
138
+ manager_of_event(manager.event_class).event_type == manager.event_type
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EvilEvents::Core::Events::Serializers
4
+ # @api public
5
+ # @since 0.1.0
6
+ module Hash
7
+ module_function
8
+
9
+ # @param event [EvilEvents::Core::Events::AbstractEvent]
10
+ # @raise [SerializationError]
11
+ # @return [::Hash]
12
+ #
13
+ # @since 0.1.0
14
+ def serialize(event)
15
+ raise SerializationError unless event.is_a?(EvilEvents::Core::Events::AbstractEvent)
16
+
17
+ { type: event.type, payload: event.payload }
18
+ end
19
+
20
+ # @param hash [::Hash]
21
+ # @raise [DeserializationError]
22
+ # @return [EvilEvents::Core::Events::AbstractEvent]
23
+ #
24
+ # @since 0.1.0
25
+ def deserialize(hash)
26
+ raise DeserializationError unless hash.is_a?(::Hash)
27
+ event_type = hash[:type] || hash['type']
28
+ event_payload = hash[:payload] || hash['payload']
29
+ raise DeserializationError unless event_type && event_payload
30
+ raise DeserializationError unless event_payload.is_a?(::Hash)
31
+
32
+ EvilEvents::BootPoint::System[:event_system].resolve_event_object(
33
+ event_type, symbolized_event_payload(event_payload)
34
+ )
35
+ end
36
+
37
+ # @param payload_hash [::Hash]
38
+ # @return [::Hash]
39
+ #
40
+ # @since 0.1.0
41
+ def symbolized_event_payload(payload_hash)
42
+ payload_hash.each_pair.each_with_object({}) do |(key, value), result_hash|
43
+ result_hash[key.to_sym] = value
44
+ end
45
+ end
46
+ private_class_method :symbolized_event_payload
47
+ end
48
+
49
+ # @since 0.1.0
50
+ register(:hash) { Hash }
51
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ class EvilEvents::Core::Events::Serializers
4
+ # @api public
5
+ # @since 0.1.0
6
+ module JSON
7
+ module_function
8
+
9
+ # @param event [EvilEvents::Core::Events::AbstractEvent]
10
+ # @raise [SerializationError]
11
+ # @return [::Hash]
12
+ #
13
+ # @since 0.1.0
14
+ def serialize(event)
15
+ raise SerializationError unless event.is_a?(EvilEvents::Core::Events::AbstractEvent)
16
+
17
+ ::JSON.generate(type: event.type, payload: event.payload)
18
+ end
19
+
20
+ # @param json [String]
21
+ # @raise [DeserializationError]
22
+ # @return [EvilEvents::Core::Events::AbstractEvent]
23
+ #
24
+ # @since 0.1.0
25
+ def deserialize(json)
26
+ raise DeserializationError unless json.is_a?(String)
27
+
28
+ begin
29
+ json_hash = ::JSON.parse(json, symbolize_names: true)
30
+ event_type = json_hash[:type]
31
+ event_payload = json_hash[:payload]
32
+ raise DeserializationError unless event_type && event_payload
33
+ rescue ::JSON::ParserError
34
+ raise DeserializationError
35
+ end
36
+
37
+ EvilEvents::BootPoint::System[:event_system].resolve_event_object(event_type, event_payload)
38
+ end
39
+ end
40
+
41
+ # @since 0.1.0
42
+ register(:json) { JSON }
43
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EvilEvents::Core::Events
4
+ # @api private
5
+ # @since 0.1.0
6
+ class Serializers
7
+ extend EvilEvents::Shared::DependencyContainer::Mixin
8
+
9
+ # @since 0.1.0
10
+ SerializersError = Class.new(StandardError)
11
+ # @since 0.1.0
12
+ SerializationError = Class.new(SerializersError)
13
+ # @since 0.1.0
14
+ DeserializationError = Class.new(SerializersError)
15
+ end
16
+ end