bmx-event_hook_client_server 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +11 -0
  3. data/Gemfile.lock +80 -0
  4. data/event_hook_client_server.gemspec +65 -0
  5. data/lib/event_hook_client_server.rb +13 -0
  6. data/lib/event_hook_client_server/client.rb +177 -0
  7. data/lib/event_hook_client_server/client/models/error.rb +16 -0
  8. data/lib/event_hook_client_server/client/models/integration.rb +25 -0
  9. data/lib/event_hook_client_server/client/models/integrations/binding.rb +21 -0
  10. data/lib/event_hook_client_server/client/response.rb +43 -0
  11. data/lib/event_hook_client_server/errors.rb +5 -0
  12. data/lib/event_hook_client_server/protobuf/event_hook_client_server/v1/enums/integrator_pb.rb +20 -0
  13. data/lib/event_hook_client_server/protobuf/event_hook_client_server/v1/messages/error_pb.rb +23 -0
  14. data/lib/event_hook_client_server/protobuf/event_hook_client_server/v1/messages/integration_pb.rb +107 -0
  15. data/lib/event_hook_client_server/protobuf/event_hook_client_server/v1/messages/pagination_pb.rb +35 -0
  16. data/lib/event_hook_client_server/protobuf/event_hook_client_server/v1/services/webhook_configurator_pb.rb +17 -0
  17. data/lib/event_hook_client_server/protobuf/event_hook_client_server/v1/services/webhook_configurator_services_pb.rb +38 -0
  18. data/lib/event_hook_client_server/refinements/hash/bury.rb +19 -0
  19. data/lib/event_hook_client_server/refinements/hash/transmute.rb +27 -0
  20. data/lib/event_hook_client_server/refinements/object/bubbling_const_lookup.rb +60 -0
  21. data/lib/event_hook_client_server/refinements/protobuf/hashable_struct_values.rb +28 -0
  22. data/lib/event_hook_client_server/refinements/protobuf/nullable_values.rb +122 -0
  23. data/lib/event_hook_client_server/server.rb +100 -0
  24. data/lib/event_hook_client_server/server/request_processor.rb +61 -0
  25. data/lib/event_hook_client_server/service.rb +9 -0
  26. data/lib/event_hook_client_server/services/grpc/struct_encoder.rb +62 -0
  27. data/lib/event_hook_client_server/types.rb +9 -0
  28. data/lib/event_hook_client_server/version.rb +8 -0
  29. metadata +143 -0
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EventHookClientServer
4
+ class Error < StandardError; end
5
+ end
@@ -0,0 +1,20 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: event_hook_client_server/protobuf/event_hook_client_server/v1/enums/integrator.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_file("event_hook_client_server/protobuf/event_hook_client_server/v1/enums/integrator.proto", :syntax => :proto3) do
8
+ add_enum "event_hook_client_server.v1.enums.Integrator" do
9
+ value :WEBHOOK, 0
10
+ end
11
+ end
12
+ end
13
+
14
+ module EventHookClientServer
15
+ module V1
16
+ module Enums
17
+ Integrator = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.enums.Integrator").enummodule
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: event_hook_client_server/protobuf/event_hook_client_server/v1/messages/error.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_file("event_hook_client_server/protobuf/event_hook_client_server/v1/messages/error.proto", :syntax => :proto3) do
8
+ add_message "event_hook_client_server.v1.messages.Error" do
9
+ optional :code, :string, 1
10
+ optional :key, :string, 2
11
+ optional :path, :string, 3
12
+ repeated :messages, :string, 4
13
+ end
14
+ end
15
+ end
16
+
17
+ module EventHookClientServer
18
+ module V1
19
+ module Messages
20
+ Error = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.Error").msgclass
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,107 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: event_hook_client_server/protobuf/event_hook_client_server/v1/messages/integration.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ require 'event_hook_client_server/protobuf/event_hook_client_server/v1/enums/integrator_pb'
7
+ require 'event_hook_client_server/protobuf/event_hook_client_server/v1/messages/pagination_pb'
8
+ require 'event_hook_client_server/protobuf/event_hook_client_server/v1/messages/error_pb'
9
+ require 'google/protobuf/wrappers_pb'
10
+ require 'google/protobuf/struct_pb'
11
+ Google::Protobuf::DescriptorPool.generated_pool.build do
12
+ add_file("event_hook_client_server/protobuf/event_hook_client_server/v1/messages/integration.proto", :syntax => :proto3) do
13
+ add_message "event_hook_client_server.v1.messages.Integration" do
14
+ optional :id, :string, 1
15
+ optional :integrator, :enum, 2, "event_hook_client_server.v1.enums.Integrator"
16
+ repeated :bindings, :message, 3, "event_hook_client_server.v1.messages.IntegrationBinding"
17
+ optional :config, :message, 4, "google.protobuf.Struct"
18
+ optional :building_id, :message, 10, "google.protobuf.StringValue"
19
+ optional :tenant_id, :message, 11, "google.protobuf.StringValue"
20
+ optional :company_id, :message, 12, "google.protobuf.StringValue"
21
+ end
22
+ add_message "event_hook_client_server.v1.messages.IntegrationConfiguration" do
23
+ optional :type, :enum, 1, "event_hook_client_server.v1.enums.Integrator"
24
+ optional :params, :message, 2, "google.protobuf.Struct"
25
+ end
26
+ add_message "event_hook_client_server.v1.messages.IntegrationBinding" do
27
+ optional :resource_type, :string, 1
28
+ optional :resource_id, :string, 2
29
+ repeated :actions, :string, 3
30
+ end
31
+ add_message "event_hook_client_server.v1.messages.IntegrationInput" do
32
+ optional :configuration, :message, 1, "event_hook_client_server.v1.messages.IntegrationInputConfiguration"
33
+ repeated :bindings, :message, 2, "event_hook_client_server.v1.messages.IntegrationBindingInput"
34
+ optional :building_id, :message, 10, "google.protobuf.StringValue"
35
+ optional :tenant_id, :message, 11, "google.protobuf.StringValue"
36
+ optional :company_id, :message, 12, "google.protobuf.StringValue"
37
+ end
38
+ add_message "event_hook_client_server.v1.messages.IntegrationInputConfiguration" do
39
+ optional :type, :enum, 1, "event_hook_client_server.v1.enums.Integrator"
40
+ optional :params, :message, 2, "google.protobuf.Struct"
41
+ end
42
+ add_message "event_hook_client_server.v1.messages.IntegrationBindingInput" do
43
+ optional :resource_type, :string, 1
44
+ repeated :actions, :string, 3
45
+ oneof :specific_id do
46
+ optional :resource_id, :string, 2
47
+ end
48
+ end
49
+ add_message "event_hook_client_server.v1.messages.IntegrationCreateRequest" do
50
+ optional :input, :message, 2, "event_hook_client_server.v1.messages.IntegrationInput"
51
+ end
52
+ add_message "event_hook_client_server.v1.messages.IntegrationUpdateRequest" do
53
+ optional :id, :string, 1
54
+ optional :input, :message, 2, "event_hook_client_server.v1.messages.IntegrationInput"
55
+ end
56
+ add_message "event_hook_client_server.v1.messages.IntegrationDestroyRequest" do
57
+ optional :id, :string, 1
58
+ end
59
+ add_message "event_hook_client_server.v1.messages.GetIntegrationRequest" do
60
+ optional :id, :string, 1
61
+ end
62
+ add_message "event_hook_client_server.v1.messages.ListIntegrationsRequest" do
63
+ optional :pagination, :message, 1, "event_hook_client_server.v1.messages.PaginationInput"
64
+ optional :query_params, :message, 2, "event_hook_client_server.v1.messages.IntegrationQueryParams"
65
+ end
66
+ add_message "event_hook_client_server.v1.messages.FindIntegrationsFromHeadersRequest" do
67
+ optional :pagination, :message, 1, "event_hook_client_server.v1.messages.PaginationInput"
68
+ optional :headers, :message, 2, "google.protobuf.Struct"
69
+ end
70
+ add_message "event_hook_client_server.v1.messages.IntegrationSingleResponse" do
71
+ optional :integration, :message, 2, "event_hook_client_server.v1.messages.Integration"
72
+ repeated :errors, :message, 3, "event_hook_client_server.v1.messages.Error"
73
+ end
74
+ add_message "event_hook_client_server.v1.messages.IntegrationsListResponse" do
75
+ repeated :integrations, :message, 2, "event_hook_client_server.v1.messages.Integration"
76
+ optional :pagination, :message, 3, "event_hook_client_server.v1.messages.Pagination"
77
+ repeated :errors, :message, 4, "event_hook_client_server.v1.messages.Error"
78
+ end
79
+ add_message "event_hook_client_server.v1.messages.IntegrationQueryParams" do
80
+ optional :building_id, :message, 10, "google.protobuf.StringValue"
81
+ optional :tenant_id, :message, 11, "google.protobuf.StringValue"
82
+ optional :company_id, :message, 12, "google.protobuf.StringValue"
83
+ end
84
+ end
85
+ end
86
+
87
+ module EventHookClientServer
88
+ module V1
89
+ module Messages
90
+ Integration = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.Integration").msgclass
91
+ IntegrationConfiguration = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.IntegrationConfiguration").msgclass
92
+ IntegrationBinding = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.IntegrationBinding").msgclass
93
+ IntegrationInput = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.IntegrationInput").msgclass
94
+ IntegrationInputConfiguration = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.IntegrationInputConfiguration").msgclass
95
+ IntegrationBindingInput = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.IntegrationBindingInput").msgclass
96
+ IntegrationCreateRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.IntegrationCreateRequest").msgclass
97
+ IntegrationUpdateRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.IntegrationUpdateRequest").msgclass
98
+ IntegrationDestroyRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.IntegrationDestroyRequest").msgclass
99
+ GetIntegrationRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.GetIntegrationRequest").msgclass
100
+ ListIntegrationsRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.ListIntegrationsRequest").msgclass
101
+ FindIntegrationsFromHeadersRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.FindIntegrationsFromHeadersRequest").msgclass
102
+ IntegrationSingleResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.IntegrationSingleResponse").msgclass
103
+ IntegrationsListResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.IntegrationsListResponse").msgclass
104
+ IntegrationQueryParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.IntegrationQueryParams").msgclass
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,35 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: event_hook_client_server/protobuf/event_hook_client_server/v1/messages/pagination.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ require 'google/protobuf/wrappers_pb'
7
+ Google::Protobuf::DescriptorPool.generated_pool.build do
8
+ add_file("event_hook_client_server/protobuf/event_hook_client_server/v1/messages/pagination.proto", :syntax => :proto3) do
9
+ add_message "event_hook_client_server.v1.messages.Cursors" do
10
+ optional :current, :message, 1, "google.protobuf.StringValue"
11
+ optional :previous, :message, 2, "google.protobuf.StringValue"
12
+ optional :next, :message, 3, "google.protobuf.StringValue"
13
+ end
14
+ add_message "event_hook_client_server.v1.messages.Pagination" do
15
+ optional :cursors, :message, 1, "event_hook_client_server.v1.messages.Cursors"
16
+ optional :count, :uint64, 2
17
+ optional :total, :uint64, 3
18
+ optional :per_page, :uint64, 4
19
+ end
20
+ add_message "event_hook_client_server.v1.messages.PaginationInput" do
21
+ optional :cursor, :string, 1
22
+ optional :per_page, :uint64, 2
23
+ end
24
+ end
25
+ end
26
+
27
+ module EventHookClientServer
28
+ module V1
29
+ module Messages
30
+ Cursors = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.Cursors").msgclass
31
+ Pagination = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.Pagination").msgclass
32
+ PaginationInput = Google::Protobuf::DescriptorPool.generated_pool.lookup("event_hook_client_server.v1.messages.PaginationInput").msgclass
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: event_hook_client_server/protobuf/event_hook_client_server/v1/services/webhook_configurator.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ require 'event_hook_client_server/protobuf/event_hook_client_server/v1/messages/integration_pb'
7
+ Google::Protobuf::DescriptorPool.generated_pool.build do
8
+ add_file("event_hook_client_server/protobuf/event_hook_client_server/v1/services/webhook_configurator.proto", :syntax => :proto3) do
9
+ end
10
+ end
11
+
12
+ module EventHookClientServer
13
+ module V1
14
+ module Services
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,38 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # Source: event_hook_client_server/protobuf/event_hook_client_server/v1/services/webhook_configurator.proto for package 'event_hook_client_server.v1.services'
3
+
4
+ require 'grpc'
5
+ require 'event_hook_client_server/protobuf/event_hook_client_server/v1/services/webhook_configurator_pb'
6
+
7
+ module EventHookClientServer
8
+ module V1
9
+ module Services
10
+ module EventHook
11
+ class Service
12
+
13
+ include GRPC::GenericService
14
+
15
+ self.marshal_class_method = :encode
16
+ self.unmarshal_class_method = :decode
17
+ self.service_name = 'event_hook_client_server.v1.services.EventHook'
18
+
19
+ # Integration
20
+ # CREATE
21
+ rpc :CreateIntegration, EventHookClientServer::V1::Messages::IntegrationCreateRequest, EventHookClientServer::V1::Messages::IntegrationSingleResponse
22
+ # UPDATE
23
+ rpc :UpdateIntegration, EventHookClientServer::V1::Messages::IntegrationUpdateRequest, EventHookClientServer::V1::Messages::IntegrationSingleResponse
24
+ # DESTROY
25
+ rpc :DestroyIntegration, EventHookClientServer::V1::Messages::IntegrationDestroyRequest, EventHookClientServer::V1::Messages::IntegrationSingleResponse
26
+ # SHOW
27
+ rpc :Integration, EventHookClientServer::V1::Messages::GetIntegrationRequest, EventHookClientServer::V1::Messages::IntegrationSingleResponse
28
+ # INDEX
29
+ rpc :Integrations, EventHookClientServer::V1::Messages::ListIntegrationsRequest, EventHookClientServer::V1::Messages::IntegrationsListResponse
30
+ #
31
+ rpc :FindIntegrationFromHeaders, EventHookClientServer::V1::Messages::FindIntegrationsFromHeadersRequest, EventHookClientServer::V1::Messages::IntegrationsListResponse
32
+ end
33
+
34
+ Stub = Service.rpc_stub_class
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EventHookClientServer
4
+ module Refinements
5
+ module Hash
6
+ module Bury
7
+ refine ::Hash do
8
+ def bury(value, path)
9
+ path = Array(path).dup
10
+ last_segment = path.pop
11
+ hash = path.reduce(self) { |h, segment| h[segment] ||= {} }
12
+ hash[last_segment] = value
13
+ self
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'event_hook_client_server/refinements/hash/bury'
4
+ using EventHookClientServer::Refinements::Hash::Bury
5
+
6
+ module EventHookClientServer
7
+ module Refinements
8
+ module Hash
9
+ module Transmute
10
+ refine ::Hash do
11
+ def transmute(modifier, path)
12
+ path = Array(path)
13
+ value = dig(*path)
14
+
15
+ return unless value
16
+
17
+ last_segment = path.pop
18
+ hash = path.reduce(self) { |h, segment| h[segment] ||= {} }
19
+ hash[last_segment] = modifier.call(value)
20
+
21
+ self
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'event_hook_client_server/service'
4
+
5
+ module EventHookClientServer
6
+ module Refinements
7
+ module Object
8
+ module BubblingConstLookup
9
+ class ConstantFinder < Service
10
+ def initialize(object, constant)
11
+ @object = object
12
+ @constant = constant
13
+ end
14
+
15
+ def call
16
+ candidates.each do |name|
17
+ return Object.const_get(name) if Object.const_defined?(name)
18
+ end
19
+
20
+ nil
21
+ end
22
+
23
+ protected
24
+
25
+ attr_reader :object
26
+ attr_reader :constant
27
+
28
+ def candidates
29
+ @candidates ||= begin
30
+ parts = object_klass.split('::')
31
+ candidates = []
32
+
33
+ parts.count.times do
34
+ candidates << [*parts, constant].join('::')
35
+ parts.pop
36
+ end
37
+
38
+ candidates
39
+ end
40
+ end
41
+
42
+ def object_klass
43
+ @object_klass ||=
44
+ if [Class, Module].include?(object.class)
45
+ object.name
46
+ else
47
+ object.class.name
48
+ end
49
+ end
50
+ end
51
+
52
+ refine Object do
53
+ def const_missing(name)
54
+ ConstantFinder.call(self, name) || super
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EventHookClientServer
4
+ module Refinements
5
+ module Protobuf
6
+ module HashableStructValues
7
+ refine Google::Protobuf::Struct do
8
+ def to_h
9
+ fields.each_with_object({}) do |(key, value), hash|
10
+ hash[key] = value.to_h
11
+ end
12
+ end
13
+ end
14
+
15
+ refine Google::Protobuf::Value do
16
+ def to_h
17
+ case kind
18
+ when :null_value then nil
19
+ when :struct_value then struct_value.to_h
20
+ when :list_value then list_value.values.map(&:to_h)
21
+ else super[kind]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'event_hook_client_server/service'
4
+
5
+ # Makes all Proto3 Value messages (aka. wrappers) act as nullable fields
6
+ # when calling `to_h`.
7
+ # The default behaviour will return `nil` if no value was passed and a hash
8
+ # containing a single `:value` key containing the passed value.
9
+ # With this refinement calling `to_h` returns `nil` if no value is passed and
10
+ # the value it self if it's present.
11
+ # The motivation behind this refinement is the absence of nullable fields in
12
+ # Proto3 and the odd choice of default values - to which the only workaround.
13
+ module EventHookClientServer
14
+ module Refinements
15
+ module Protobuf
16
+ module NullableValues
17
+ # Recursively traverses hashes and arrays looking for a Hash value
18
+ # that looks like `{ value: 'something' }` and who's coresponding
19
+ # message type class name ends with `Value`. When found the hash
20
+ # key / array element is deleted and in it's place the object stored
21
+ # under the `value` key is placed.
22
+ class HashProcessor < EventHookClientServer::Service
23
+ def initialize(hash, object, parent_hash = nil, parent_key = nil)
24
+ @hash = hash
25
+ @object = object
26
+ @parent_hash = parent_hash
27
+ @parent_key = parent_key
28
+ end
29
+
30
+ def call
31
+ if value? && parent_hash
32
+ parent_hash.delete(parent_key) if parent_hash.is_a?(Hash)
33
+ parent_hash[parent_key] = hash[:value]
34
+ return parent_hash[parent_key]
35
+ end
36
+
37
+ case hash
38
+ when Hash then process_hash!
39
+ when Array then process_array!
40
+ else object
41
+ end
42
+
43
+ hash
44
+ end
45
+
46
+ protected
47
+
48
+ attr_reader :hash
49
+ attr_reader :object
50
+ attr_reader :parent_hash
51
+ attr_reader :parent_key
52
+ alias array hash
53
+
54
+ private
55
+
56
+ def process_hash!
57
+ hash.keys.each do |key|
58
+ obj =
59
+ if object.is_a?(Google::Protobuf::Map)
60
+ object[key]
61
+ else
62
+ object.send(key)
63
+ end
64
+
65
+ self.class.call(hash[key], obj, hash, key)
66
+ end
67
+ end
68
+
69
+ def process_array!
70
+ array.each.with_index do |element, i|
71
+ self.class.call(element, object[i], array, i)
72
+ end
73
+ end
74
+
75
+ def value_class?
76
+ object.class.name.match?(/^.+Value$/)
77
+ end
78
+
79
+ def value_hash?
80
+ hash.key?(:value) && hash.keys.count == 1
81
+ end
82
+
83
+ def value?
84
+ value_class? && value_hash?
85
+ end
86
+ end
87
+
88
+ # This is terribly hacky but necessary due to the way that Google
89
+ # implemented messages in the Protobuf gem.
90
+ # Each message is just a constant representing an unnamed class that's
91
+ # build in the C extension. That means that each class implements it's
92
+ # own `to_h`, `to_json`, ... directly in C. The C implementation for
93
+ # those methods is self-contained meaning that each object knows how
94
+ # to marshall and serialize all of it's children - TL:DR no visitor
95
+ # pattern is used. E.g. given two objects `foo` and `bar` where
96
+ # `bar = { bar: 'bar' }` and `foo = { foo: bar }`, calling `foo.to_h`
97
+ # WILL NOT call `to_h` on `bar`, because `foo` knows how and will
98
+ # serialize `bar`.
99
+ # The only thing they have in common is that they all extend
100
+ # `MessageExts` which provides class methods. Some of the more complex
101
+ # deserialization and marshalling logic is implemented there.
102
+ message_klasses =
103
+ ObjectSpace
104
+ .each_object(Class)
105
+ .select { |klass| klass < Google::Protobuf::MessageExts }
106
+
107
+ message_klasses.each do |klass|
108
+ refine klass do
109
+ def to_h
110
+ hash = super
111
+
112
+ return unless hash
113
+
114
+ HashProcessor.call(hash, self)
115
+ hash
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end