smart_message 0.0.4 → 0.0.6

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.
@@ -0,0 +1,141 @@
1
+ # lib/smart_message/property_validations.rb
2
+ # encoding: utf-8
3
+ # frozen_string_literal: true
4
+
5
+ module SmartMessage
6
+ module PropertyValidations
7
+ def self.included(base)
8
+ base.extend(ClassMethods)
9
+ base.class_eval do
10
+ @property_validators = {}
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ def property(property_name, options = {})
16
+ # Extract our custom options before passing to Hashie::Dash
17
+ # Note: Hashie's 'message' option only works with 'required', so we use 'validation_message'
18
+ validator = options.delete(:validate)
19
+ validation_message = options.delete(:validation_message)
20
+
21
+ # Call original property method first
22
+ super(property_name, options)
23
+
24
+ # Then store validator if provided
25
+ if validator
26
+ @property_validators ||= {}
27
+ @property_validators[property_name.to_sym] = {
28
+ validator: validator,
29
+ message: validation_message || "Validation failed for property '#{property_name}'"
30
+ }
31
+
32
+ # Note: We don't override setter methods since they may conflict with Hashie::Dash
33
+ # Instead, validation happens during validate! calls
34
+ end
35
+ end
36
+
37
+ def property_validator(property_name)
38
+ @property_validators&.[](property_name.to_sym)
39
+ end
40
+
41
+ def property_validators
42
+ @property_validators&.dup || {}
43
+ end
44
+
45
+ def validated_properties
46
+ @property_validators&.keys || []
47
+ end
48
+
49
+ # Validate all properties with validators
50
+ def validate_all(instance)
51
+ validated_properties.each do |property_name|
52
+ validator_info = property_validator(property_name)
53
+ next unless validator_info
54
+
55
+ value = instance.send(property_name)
56
+ validator = validator_info[:validator]
57
+ error_message = validator_info[:message]
58
+
59
+ # Skip validation if value is nil and property is not required
60
+ next if value.nil? && !instance.class.required_properties.include?(property_name)
61
+
62
+ # Perform validation
63
+ is_valid = case validator
64
+ when Proc
65
+ instance.instance_exec(value, &validator)
66
+ when Symbol
67
+ instance.send(validator, value)
68
+ when Regexp
69
+ !!(value.to_s =~ validator)
70
+ when Class
71
+ value.is_a?(validator)
72
+ when Array
73
+ validator.include?(value)
74
+ when Range
75
+ validator.include?(value)
76
+ else
77
+ value == validator
78
+ end
79
+
80
+ unless is_valid
81
+ raise SmartMessage::Errors::ValidationError, "#{instance.class.name}##{property_name}: #{error_message}"
82
+ end
83
+ end
84
+ true
85
+ end
86
+ end
87
+
88
+ # Instance methods
89
+ def validate!
90
+ self.class.validate_all(self)
91
+ end
92
+
93
+ def valid?
94
+ validate!
95
+ true
96
+ rescue SmartMessage::Errors::ValidationError
97
+ false
98
+ end
99
+
100
+ def validation_errors
101
+ errors = []
102
+ self.class.validated_properties.each do |property_name|
103
+ validator_info = self.class.property_validator(property_name)
104
+ next unless validator_info
105
+
106
+ value = send(property_name)
107
+ validator = validator_info[:validator]
108
+
109
+ # Skip validation if value is nil and property is not required
110
+ next if value.nil? && !self.class.required_properties.include?(property_name)
111
+
112
+ # Perform validation
113
+ is_valid = case validator
114
+ when Proc
115
+ instance_exec(value, &validator)
116
+ when Symbol
117
+ send(validator, value)
118
+ when Regexp
119
+ !!(value.to_s =~ validator)
120
+ when Class
121
+ value.is_a?(validator)
122
+ when Array
123
+ validator.include?(value)
124
+ when Range
125
+ validator.include?(value)
126
+ else
127
+ value == validator
128
+ end
129
+
130
+ unless is_valid
131
+ errors << {
132
+ property: property_name,
133
+ value: value,
134
+ message: validator_info[:message]
135
+ }
136
+ end
137
+ end
138
+ errors
139
+ end
140
+ end
141
+ end
@@ -35,8 +35,9 @@ module SmartMessage
35
35
  # Subscribe to a message class
36
36
  # @param message_class [String] The message class name
37
37
  # @param process_method [String] The processing method identifier
38
- def subscribe(message_class, process_method)
39
- @dispatcher.add(message_class, process_method)
38
+ # @param filter_options [Hash] Optional filtering criteria
39
+ def subscribe(message_class, process_method, filter_options = {})
40
+ @dispatcher.add(message_class, process_method, filter_options)
40
41
  end
41
42
 
42
43
  # Unsubscribe from a specific message class and process method
@@ -46,8 +46,8 @@ module SmartMessage
46
46
  end
47
47
 
48
48
  # Subscribe to a message class (Redis channel)
49
- def subscribe(message_class, process_method)
50
- super(message_class, process_method)
49
+ def subscribe(message_class, process_method, filter_options = {})
50
+ super(message_class, process_method, filter_options)
51
51
 
52
52
  @mutex.synchronize do
53
53
  @subscribed_channels.add(message_class)
@@ -3,5 +3,5 @@
3
3
  # frozen_string_literal: true
4
4
 
5
5
  module SmartMessage
6
- VERSION = '0.0.4'
6
+ VERSION = '0.0.6'
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_message
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
@@ -199,6 +199,7 @@ files:
199
199
  - bin/console
200
200
  - bin/setup
201
201
  - docs/README.md
202
+ - docs/addressing.md
202
203
  - docs/architecture.md
203
204
  - docs/dispatcher.md
204
205
  - docs/examples.md
@@ -218,6 +219,9 @@ files:
218
219
  - examples/04_redis_smart_home_iot.rb
219
220
  - examples/05_proc_handlers.rb
220
221
  - examples/06_custom_logger_example.rb
222
+ - examples/07_error_handling_scenarios.rb
223
+ - examples/08_entity_addressing_basic.rb
224
+ - examples/08_entity_addressing_with_filtering.rb
221
225
  - examples/README.md
222
226
  - examples/smart_home_iot_dataflow.md
223
227
  - examples/tmux_chat/README.md
@@ -238,6 +242,7 @@ files:
238
242
  - lib/smart_message/logger/base.rb
239
243
  - lib/smart_message/logger/default.rb
240
244
  - lib/smart_message/property_descriptions.rb
245
+ - lib/smart_message/property_validations.rb
241
246
  - lib/smart_message/serializer.rb
242
247
  - lib/smart_message/serializer/base.rb
243
248
  - lib/smart_message/serializer/json.rb