cmdx 1.1.2 → 1.5.0
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.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.cursor/prompts/docs.md +4 -1
- data/.cursor/prompts/llms.md +20 -0
- data/.cursor/prompts/rspec.md +4 -1
- data/.cursor/prompts/yardoc.md +3 -2
- data/.cursor/rules/cursor-instructions.mdc +56 -1
- data/.irbrc +6 -0
- data/.rubocop.yml +29 -18
- data/CHANGELOG.md +5 -133
- data/LLM.md +3317 -0
- data/README.md +68 -44
- data/docs/attributes/coercions.md +162 -0
- data/docs/attributes/defaults.md +90 -0
- data/docs/attributes/definitions.md +281 -0
- data/docs/attributes/naming.md +78 -0
- data/docs/attributes/validations.md +309 -0
- data/docs/basics/chain.md +56 -249
- data/docs/basics/context.md +56 -289
- data/docs/basics/execution.md +114 -0
- data/docs/basics/setup.md +37 -334
- data/docs/callbacks.md +89 -467
- data/docs/deprecation.md +91 -174
- data/docs/getting_started.md +212 -202
- data/docs/internationalization.md +11 -647
- data/docs/interruptions/exceptions.md +23 -198
- data/docs/interruptions/faults.md +71 -151
- data/docs/interruptions/halt.md +109 -186
- data/docs/logging.md +44 -256
- data/docs/middlewares.md +113 -426
- data/docs/outcomes/result.md +81 -228
- data/docs/outcomes/states.md +33 -221
- data/docs/outcomes/statuses.md +21 -311
- data/docs/tips_and_tricks.md +120 -70
- data/docs/workflows.md +99 -283
- data/lib/cmdx/.DS_Store +0 -0
- data/lib/cmdx/attribute.rb +229 -0
- data/lib/cmdx/attribute_registry.rb +94 -0
- data/lib/cmdx/attribute_value.rb +193 -0
- data/lib/cmdx/callback_registry.rb +69 -77
- data/lib/cmdx/chain.rb +56 -73
- data/lib/cmdx/coercion_registry.rb +52 -68
- data/lib/cmdx/coercions/array.rb +19 -18
- data/lib/cmdx/coercions/big_decimal.rb +20 -24
- data/lib/cmdx/coercions/boolean.rb +26 -25
- data/lib/cmdx/coercions/complex.rb +21 -22
- data/lib/cmdx/coercions/date.rb +25 -23
- data/lib/cmdx/coercions/date_time.rb +24 -25
- data/lib/cmdx/coercions/float.rb +25 -22
- data/lib/cmdx/coercions/hash.rb +31 -32
- data/lib/cmdx/coercions/integer.rb +30 -24
- data/lib/cmdx/coercions/rational.rb +29 -24
- data/lib/cmdx/coercions/string.rb +19 -22
- data/lib/cmdx/coercions/symbol.rb +37 -0
- data/lib/cmdx/coercions/time.rb +26 -25
- data/lib/cmdx/configuration.rb +49 -108
- data/lib/cmdx/context.rb +222 -44
- data/lib/cmdx/deprecator.rb +61 -0
- data/lib/cmdx/errors.rb +42 -252
- data/lib/cmdx/exceptions.rb +39 -0
- data/lib/cmdx/faults.rb +78 -39
- data/lib/cmdx/freezer.rb +51 -0
- data/lib/cmdx/identifier.rb +30 -0
- data/lib/cmdx/locale.rb +52 -0
- data/lib/cmdx/log_formatters/json.rb +21 -22
- data/lib/cmdx/log_formatters/key_value.rb +20 -22
- data/lib/cmdx/log_formatters/line.rb +15 -22
- data/lib/cmdx/log_formatters/logstash.rb +22 -23
- data/lib/cmdx/log_formatters/raw.rb +16 -22
- data/lib/cmdx/middleware_registry.rb +70 -74
- data/lib/cmdx/middlewares/correlate.rb +90 -54
- data/lib/cmdx/middlewares/runtime.rb +58 -0
- data/lib/cmdx/middlewares/timeout.rb +48 -68
- data/lib/cmdx/railtie.rb +12 -45
- data/lib/cmdx/result.rb +229 -314
- data/lib/cmdx/task.rb +194 -366
- data/lib/cmdx/utils/call.rb +49 -0
- data/lib/cmdx/utils/condition.rb +71 -0
- data/lib/cmdx/utils/format.rb +61 -0
- data/lib/cmdx/validator_registry.rb +63 -72
- data/lib/cmdx/validators/exclusion.rb +38 -67
- data/lib/cmdx/validators/format.rb +48 -49
- data/lib/cmdx/validators/inclusion.rb +43 -74
- data/lib/cmdx/validators/length.rb +91 -154
- data/lib/cmdx/validators/numeric.rb +87 -162
- data/lib/cmdx/validators/presence.rb +37 -50
- data/lib/cmdx/version.rb +1 -1
- data/lib/cmdx/worker.rb +178 -0
- data/lib/cmdx/workflow.rb +85 -81
- data/lib/cmdx.rb +19 -13
- data/lib/generators/cmdx/install_generator.rb +14 -13
- data/lib/generators/cmdx/task_generator.rb +25 -50
- data/lib/generators/cmdx/templates/install.rb +11 -46
- data/lib/generators/cmdx/templates/task.rb.tt +3 -2
- data/lib/locales/en.yml +18 -4
- data/src/cmdx-logo.png +0 -0
- metadata +32 -116
- data/docs/ai_prompts.md +0 -393
- data/docs/basics/call.md +0 -317
- data/docs/configuration.md +0 -344
- data/docs/parameters/coercions.md +0 -396
- data/docs/parameters/defaults.md +0 -335
- data/docs/parameters/definitions.md +0 -446
- data/docs/parameters/namespacing.md +0 -378
- data/docs/parameters/validations.md +0 -405
- data/docs/testing.md +0 -553
- data/lib/cmdx/callback.rb +0 -53
- data/lib/cmdx/chain_inspector.rb +0 -56
- data/lib/cmdx/chain_serializer.rb +0 -63
- data/lib/cmdx/coercion.rb +0 -57
- data/lib/cmdx/coercions/virtual.rb +0 -29
- data/lib/cmdx/core_ext/hash.rb +0 -83
- data/lib/cmdx/core_ext/module.rb +0 -98
- data/lib/cmdx/core_ext/object.rb +0 -125
- data/lib/cmdx/correlator.rb +0 -122
- data/lib/cmdx/error.rb +0 -67
- data/lib/cmdx/fault.rb +0 -140
- data/lib/cmdx/immutator.rb +0 -52
- data/lib/cmdx/lazy_struct.rb +0 -246
- data/lib/cmdx/log_formatters/pretty_json.rb +0 -40
- data/lib/cmdx/log_formatters/pretty_key_value.rb +0 -38
- data/lib/cmdx/log_formatters/pretty_line.rb +0 -41
- data/lib/cmdx/logger.rb +0 -49
- data/lib/cmdx/logger_ansi.rb +0 -68
- data/lib/cmdx/logger_serializer.rb +0 -116
- data/lib/cmdx/middleware.rb +0 -70
- data/lib/cmdx/parameter.rb +0 -312
- data/lib/cmdx/parameter_evaluator.rb +0 -231
- data/lib/cmdx/parameter_inspector.rb +0 -66
- data/lib/cmdx/parameter_registry.rb +0 -106
- data/lib/cmdx/parameter_serializer.rb +0 -59
- data/lib/cmdx/result_ansi.rb +0 -71
- data/lib/cmdx/result_inspector.rb +0 -71
- data/lib/cmdx/result_logger.rb +0 -59
- data/lib/cmdx/result_serializer.rb +0 -104
- data/lib/cmdx/rspec/matchers.rb +0 -28
- data/lib/cmdx/rspec/result_matchers/be_executed.rb +0 -42
- data/lib/cmdx/rspec/result_matchers/be_failed_task.rb +0 -94
- data/lib/cmdx/rspec/result_matchers/be_skipped_task.rb +0 -94
- data/lib/cmdx/rspec/result_matchers/be_state_matchers.rb +0 -59
- data/lib/cmdx/rspec/result_matchers/be_status_matchers.rb +0 -57
- data/lib/cmdx/rspec/result_matchers/be_successful_task.rb +0 -87
- data/lib/cmdx/rspec/result_matchers/have_bad_outcome.rb +0 -51
- data/lib/cmdx/rspec/result_matchers/have_caused_failure.rb +0 -58
- data/lib/cmdx/rspec/result_matchers/have_chain_index.rb +0 -59
- data/lib/cmdx/rspec/result_matchers/have_context.rb +0 -86
- data/lib/cmdx/rspec/result_matchers/have_empty_metadata.rb +0 -54
- data/lib/cmdx/rspec/result_matchers/have_good_outcome.rb +0 -52
- data/lib/cmdx/rspec/result_matchers/have_metadata.rb +0 -114
- data/lib/cmdx/rspec/result_matchers/have_preserved_context.rb +0 -66
- data/lib/cmdx/rspec/result_matchers/have_received_thrown_failure.rb +0 -64
- data/lib/cmdx/rspec/result_matchers/have_runtime.rb +0 -78
- data/lib/cmdx/rspec/result_matchers/have_thrown_failure.rb +0 -76
- data/lib/cmdx/rspec/task_matchers/be_well_formed_task.rb +0 -62
- data/lib/cmdx/rspec/task_matchers/have_callback.rb +0 -85
- data/lib/cmdx/rspec/task_matchers/have_cmd_setting.rb +0 -68
- data/lib/cmdx/rspec/task_matchers/have_executed_callbacks.rb +0 -92
- data/lib/cmdx/rspec/task_matchers/have_middleware.rb +0 -46
- data/lib/cmdx/rspec/task_matchers/have_parameter.rb +0 -181
- data/lib/cmdx/task_deprecator.rb +0 -58
- data/lib/cmdx/task_processor.rb +0 -246
- data/lib/cmdx/task_serializer.rb +0 -57
- data/lib/cmdx/utils/ansi_color.rb +0 -73
- data/lib/cmdx/utils/log_timestamp.rb +0 -36
- data/lib/cmdx/utils/monotonic_runtime.rb +0 -34
- data/lib/cmdx/utils/name_affix.rb +0 -52
- data/lib/cmdx/validator.rb +0 -57
- data/lib/generators/cmdx/templates/workflow.rb.tt +0 -7
- data/lib/generators/cmdx/workflow_generator.rb +0 -84
- data/lib/locales/ar.yml +0 -35
- data/lib/locales/cs.yml +0 -35
- data/lib/locales/da.yml +0 -35
- data/lib/locales/de.yml +0 -35
- data/lib/locales/el.yml +0 -35
- data/lib/locales/es.yml +0 -35
- data/lib/locales/fi.yml +0 -35
- data/lib/locales/fr.yml +0 -35
- data/lib/locales/he.yml +0 -35
- data/lib/locales/hi.yml +0 -35
- data/lib/locales/it.yml +0 -35
- data/lib/locales/ja.yml +0 -35
- data/lib/locales/ko.yml +0 -35
- data/lib/locales/nl.yml +0 -35
- data/lib/locales/no.yml +0 -35
- data/lib/locales/pl.yml +0 -35
- data/lib/locales/pt.yml +0 -35
- data/lib/locales/ru.yml +0 -35
- data/lib/locales/sv.yml +0 -35
- data/lib/locales/th.yml +0 -35
- data/lib/locales/tr.yml +0 -35
- data/lib/locales/vi.yml +0 -35
- data/lib/locales/zh.yml +0 -35
data/lib/cmdx/coercions/date.rb
CHANGED
@@ -2,43 +2,45 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Converts various input types to Date format
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
7
|
+
# Handles conversion from strings, Date objects, DateTime objects, Time objects,
|
8
|
+
# and other date-like values to Date objects using Ruby's built-in parsing
|
9
|
+
# capabilities and optional custom format parsing.
|
10
|
+
module Date
|
10
11
|
|
12
|
+
extend self
|
13
|
+
|
14
|
+
# Types that are already date-like and don't need conversion
|
11
15
|
ANALOG_TYPES = %w[Date DateTime Time].freeze
|
12
16
|
|
13
|
-
# Converts
|
14
|
-
#
|
15
|
-
# @param value [Object] the value to convert to a Date
|
16
|
-
# @param options [Hash] optional configuration
|
17
|
-
# @option options [String] :strptime custom date format for parsing
|
18
|
-
#
|
19
|
-
# @return [Date] the converted Date object
|
17
|
+
# Converts a value to a Date object
|
20
18
|
#
|
21
|
-
# @
|
19
|
+
# @param value [Object] The value to convert to a Date
|
20
|
+
# @param options [Hash] Optional configuration parameters
|
21
|
+
# @option options [String] :strptime Custom date format string for parsing
|
22
22
|
#
|
23
|
-
# @
|
24
|
-
# Coercions::Date.call('2023-12-25') #=> #<Date: 2023-12-25>
|
23
|
+
# @return [Date] The converted Date object
|
25
24
|
#
|
26
|
-
# @
|
27
|
-
# Coercions::Date.call('25/12/2023', strptime: '%d/%m/%Y') #=> #<Date: 2023-12-25>
|
25
|
+
# @raise [CoercionError] If the value cannot be converted to a Date
|
28
26
|
#
|
29
|
-
# @example
|
30
|
-
#
|
27
|
+
# @example Convert string to Date using default parsing
|
28
|
+
# Date.call("2023-12-25") # => #<Date: 2023-12-25>
|
29
|
+
# Date.call("Dec 25, 2023") # => #<Date: 2023-12-25>
|
30
|
+
# @example Convert string using custom format
|
31
|
+
# Date.call("25/12/2023", strptime: "%d/%m/%Y") # => #<Date: 2023-12-25>
|
32
|
+
# Date.call("12-25-2023", strptime: "%m-%d-%Y") # => #<Date: 2023-12-25>
|
33
|
+
# @example Return existing Date objects unchanged
|
34
|
+
# Date.call(Date.new(2023, 12, 25)) # => #<Date: 2023-12-25>
|
35
|
+
# Date.call(DateTime.new(2023, 12, 25)) # => #<Date: 2023-12-25>
|
31
36
|
def call(value, options = {})
|
32
37
|
return value if ANALOG_TYPES.include?(value.class.name)
|
33
38
|
return ::Date.strptime(value, options[:strptime]) if options[:strptime]
|
34
39
|
|
35
40
|
::Date.parse(value)
|
36
41
|
rescue TypeError, ::Date::Error
|
37
|
-
|
38
|
-
|
39
|
-
type: "date",
|
40
|
-
default: "could not coerce into a date"
|
41
|
-
)
|
42
|
+
type = Locale.t("cmdx.types.date")
|
43
|
+
raise CoercionError, Locale.t("cmdx.coercions.into_a", type:)
|
42
44
|
end
|
43
45
|
|
44
46
|
end
|
@@ -2,45 +2,44 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Converts various input types to DateTime format
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
7
|
+
# Handles conversion from date strings, Date objects, Time objects, and other
|
8
|
+
# values that can be converted to DateTime using Ruby's DateTime.parse method
|
9
|
+
# or custom strptime formats.
|
10
|
+
module DateTime
|
11
|
+
|
12
|
+
extend self
|
11
13
|
|
12
14
|
ANALOG_TYPES = %w[Date DateTime Time].freeze
|
13
15
|
|
14
|
-
# Converts
|
15
|
-
#
|
16
|
-
# @param value [Object] the value to convert to a DateTime
|
17
|
-
# @param options [Hash] optional configuration
|
18
|
-
# @option options [String] :strptime custom format string for parsing
|
19
|
-
#
|
20
|
-
# @return [DateTime] the converted DateTime object
|
16
|
+
# Converts a value to a DateTime
|
21
17
|
#
|
22
|
-
# @
|
18
|
+
# @param value [Object] The value to convert to DateTime
|
19
|
+
# @param options [Hash] Optional configuration parameters
|
20
|
+
# @option options [String] :strptime Custom date format string for parsing
|
23
21
|
#
|
24
|
-
# @
|
25
|
-
# Coercions::DateTime.call('2023-12-25') #=> #<DateTime: 2023-12-25T00:00:00+00:00>
|
22
|
+
# @return [DateTime] The converted DateTime value
|
26
23
|
#
|
27
|
-
# @
|
28
|
-
# Coercions::DateTime.call('25/12/2023', strptime: '%d/%m/%Y') #=> #<DateTime: 2023-12-25T00:00:00+00:00>
|
24
|
+
# @raise [CoercionError] If the value cannot be converted to DateTime
|
29
25
|
#
|
30
|
-
# @example
|
31
|
-
#
|
32
|
-
#
|
26
|
+
# @example Convert date strings to DateTime
|
27
|
+
# DateTime.call("2023-12-25") # => #<DateTime: 2023-12-25T00:00:00+00:00>
|
28
|
+
# DateTime.call("Dec 25, 2023") # => #<DateTime: 2023-12-25T00:00:00+00:00>
|
29
|
+
# @example Convert with custom strptime format
|
30
|
+
# DateTime.call("25/12/2023", strptime: "%d/%m/%Y")
|
31
|
+
# # => #<DateTime: 2023-12-25T00:00:00+00:00>
|
32
|
+
# @example Convert existing date objects
|
33
|
+
# DateTime.call(Date.new(2023, 12, 25)) # => #<DateTime: 2023-12-25T00:00:00+00:00>
|
34
|
+
# DateTime.call(Time.new(2023, 12, 25)) # => #<DateTime: 2023-12-25T00:00:00+00:00>
|
33
35
|
def call(value, options = {})
|
34
36
|
return value if ANALOG_TYPES.include?(value.class.name)
|
35
37
|
return ::DateTime.strptime(value, options[:strptime]) if options[:strptime]
|
36
38
|
|
37
39
|
::DateTime.parse(value)
|
38
40
|
rescue TypeError, ::Date::Error
|
39
|
-
|
40
|
-
|
41
|
-
type: "datetime",
|
42
|
-
default: "could not coerce into a datetime"
|
43
|
-
)
|
41
|
+
type = Locale.t("cmdx.types.date_time")
|
42
|
+
raise CoercionError, Locale.t("cmdx.coercions.into_a", type:)
|
44
43
|
end
|
45
44
|
|
46
45
|
end
|
data/lib/cmdx/coercions/float.rb
CHANGED
@@ -2,36 +2,39 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Converts various input types to Float format
|
6
6
|
#
|
7
|
-
#
|
8
|
-
# Ruby's
|
9
|
-
|
7
|
+
# Handles conversion from numeric strings, integers, and other numeric types
|
8
|
+
# that can be converted to floats using Ruby's Float() method.
|
9
|
+
module Float
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
# @param _options [Hash] optional configuration (currently unused)
|
11
|
+
extend self
|
12
|
+
|
13
|
+
# Converts a value to a Float
|
15
14
|
#
|
16
|
-
# @
|
15
|
+
# @param value [Object] The value to convert to a float
|
16
|
+
# @param options [Hash] Optional configuration parameters (currently unused)
|
17
|
+
# @option options [Object] :unused Currently no options are used
|
17
18
|
#
|
18
|
-
# @
|
19
|
+
# @return [Float] The converted float value
|
19
20
|
#
|
20
|
-
# @
|
21
|
-
# Coercions::Float.call("3.14") #=> 3.14
|
22
|
-
# Coercions::Float.call("42") #=> 42.0
|
21
|
+
# @raise [CoercionError] If the value cannot be converted to a float
|
23
22
|
#
|
24
|
-
# @example
|
25
|
-
#
|
26
|
-
#
|
27
|
-
|
23
|
+
# @example Convert numeric strings to float
|
24
|
+
# Float.call("123") # => 123.0
|
25
|
+
# Float.call("123.456") # => 123.456
|
26
|
+
# Float.call("-42.5") # => -42.5
|
27
|
+
# Float.call("1.23e4") # => 12300.0
|
28
|
+
# @example Convert numeric types to float
|
29
|
+
# Float.call(42) # => 42.0
|
30
|
+
# Float.call(BigDecimal("123.456")) # => 123.456
|
31
|
+
# Float.call(Rational(3, 4)) # => 0.75
|
32
|
+
# Float.call(Complex(5.0, 0)) # => 5.0
|
33
|
+
def call(value, options = {})
|
28
34
|
Float(value)
|
29
35
|
rescue ArgumentError, RangeError, TypeError
|
30
|
-
|
31
|
-
|
32
|
-
type: "float",
|
33
|
-
default: "could not coerce into a float"
|
34
|
-
)
|
36
|
+
type = Locale.t("cmdx.types.float")
|
37
|
+
raise CoercionError, Locale.t("cmdx.coercions.into_a", type:)
|
35
38
|
end
|
36
39
|
|
37
40
|
end
|
data/lib/cmdx/coercions/hash.rb
CHANGED
@@ -2,41 +2,40 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Coerces various input types into Hash objects
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
7
|
+
# Supports conversion from:
|
8
|
+
# - Hash objects (returned as-is)
|
9
|
+
# - Array objects (converted using Hash[*array])
|
10
|
+
# - JSON strings starting with "{" (parsed into Hash)
|
11
|
+
# - Other types raise CoercionError
|
12
|
+
module Hash
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
# @param _options [Hash] optional configuration (currently unused)
|
16
|
-
#
|
17
|
-
# @return [Hash] the converted hash value
|
14
|
+
extend self
|
15
|
+
|
16
|
+
# Coerces a value into a Hash
|
18
17
|
#
|
19
|
-
# @
|
20
|
-
# @
|
21
|
-
# @
|
22
|
-
# @raise [TypeError] if the value type is not supported
|
18
|
+
# @param value [Object] The value to coerce
|
19
|
+
# @param options [Hash] Additional options (currently unused)
|
20
|
+
# @option options [Symbol] :strict Whether to enforce strict conversion
|
23
21
|
#
|
24
|
-
# @
|
25
|
-
# Coercions::Hash.call('{"a": 1, "b": 2}') #=> {"a" => 1, "b" => 2}
|
22
|
+
# @return [Hash] The coerced hash value
|
26
23
|
#
|
27
|
-
# @
|
28
|
-
# Coercions::Hash.call(["a", 1, "b", 2]) #=> {"a" => 1, "b" => 2}
|
24
|
+
# @raise [CoercionError] When the value cannot be coerced to a Hash
|
29
25
|
#
|
30
|
-
# @example
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
# @example Coerce from existing Hash
|
27
|
+
# Hash.call({a: 1, b: 2}) # => {a: 1, b: 2}
|
28
|
+
# @example Coerce from Array
|
29
|
+
# Hash.call([:a, 1, :b, 2]) # => {a: 1, b: 2}
|
30
|
+
# @example Coerce from JSON string
|
31
|
+
# Hash.call('{"key": "value"}') # => {"key" => "value"}
|
32
|
+
def call(value, options = {})
|
33
|
+
if value.is_a?(::Hash)
|
35
34
|
value
|
36
|
-
|
35
|
+
elsif value.is_a?(::Array)
|
37
36
|
::Hash[*value]
|
38
|
-
|
39
|
-
|
37
|
+
elsif value.is_a?(::String) && value.start_with?("{")
|
38
|
+
JSON.parse(value)
|
40
39
|
else
|
41
40
|
raise_coercion_error!
|
42
41
|
end
|
@@ -46,12 +45,12 @@ module CMDx
|
|
46
45
|
|
47
46
|
private
|
48
47
|
|
48
|
+
# Raises a CoercionError with localized message
|
49
|
+
#
|
50
|
+
# @raise [CoercionError] Always raised with localized error message
|
49
51
|
def raise_coercion_error!
|
50
|
-
|
51
|
-
|
52
|
-
type: "hash",
|
53
|
-
default: "could not coerce into a hash"
|
54
|
-
)
|
52
|
+
type = Locale.t("cmdx.types.hash")
|
53
|
+
raise CoercionError, Locale.t("cmdx.coercions.into_a", type:)
|
55
54
|
end
|
56
55
|
|
57
56
|
end
|
@@ -2,37 +2,43 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Converts various input types to Integer format
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
7
|
+
# Handles conversion from strings, numbers, and other values to integers
|
8
|
+
# using Ruby's Integer() method. Raises CoercionError for values that
|
9
|
+
# cannot be converted to integers.
|
10
|
+
module Integer
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
# @param _options [Hash] optional configuration (currently unused)
|
12
|
+
extend self
|
13
|
+
|
14
|
+
# Converts a value to an Integer
|
15
15
|
#
|
16
|
-
# @
|
16
|
+
# @param value [Object] The value to convert to an integer
|
17
|
+
# @param options [Hash] Optional configuration parameters (currently unused)
|
18
|
+
# @option options [Object] :unused Currently no options are used
|
17
19
|
#
|
18
|
-
# @
|
20
|
+
# @return [Integer] The converted integer value
|
19
21
|
#
|
20
|
-
# @
|
21
|
-
# Coercions::Integer.call("123") #=> 123
|
22
|
-
# Coercions::Integer.call("-456") #=> -456
|
22
|
+
# @raise [CoercionError] If the value cannot be converted to an integer
|
23
23
|
#
|
24
|
-
# @example
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
|
24
|
+
# @example Convert numeric strings to integers
|
25
|
+
# Integer.call("42") # => 42
|
26
|
+
# Integer.call("-123") # => -123
|
27
|
+
# Integer.call("0") # => 0
|
28
|
+
# @example Convert numeric types to integers
|
29
|
+
# Integer.call(42.0) # => 42
|
30
|
+
# Integer.call(3.14) # => 3
|
31
|
+
# Integer.call(0.0) # => 0
|
32
|
+
# @example Handle edge cases
|
33
|
+
# Integer.call("") # => 0
|
34
|
+
# Integer.call(nil) # => 0
|
35
|
+
# Integer.call(false) # => 0
|
36
|
+
# Integer.call(true) # => 1
|
37
|
+
def call(value, options = {})
|
29
38
|
Integer(value)
|
30
|
-
rescue ArgumentError, FloatDomainError, RangeError, TypeError
|
31
|
-
|
32
|
-
|
33
|
-
type: "integer",
|
34
|
-
default: "could not coerce into an integer"
|
35
|
-
)
|
39
|
+
rescue ArgumentError, FloatDomainError, RangeError, TypeError
|
40
|
+
type = Locale.t("cmdx.types.integer")
|
41
|
+
raise CoercionError, Locale.t("cmdx.coercions.into_an", type:)
|
36
42
|
end
|
37
43
|
|
38
44
|
end
|
@@ -2,37 +2,42 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Converts various input types to Rational format
|
6
6
|
#
|
7
|
-
#
|
8
|
-
# using Ruby's
|
9
|
-
|
7
|
+
# Handles conversion from strings, numbers, and other values to rational
|
8
|
+
# numbers using Ruby's Rational() method. Raises CoercionError for values
|
9
|
+
# that cannot be converted to rational numbers.
|
10
|
+
module Rational
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
# @param _options [Hash] optional configuration (currently unused)
|
15
|
-
#
|
16
|
-
# @return [Rational] the converted rational value
|
12
|
+
extend self
|
13
|
+
|
14
|
+
# Converts a value to a Rational
|
17
15
|
#
|
18
|
-
# @
|
16
|
+
# @param value [Object] The value to convert to a rational number
|
17
|
+
# @param options [Hash] Optional configuration parameters (currently unused)
|
18
|
+
# @option options [Object] :unused Currently no options are used
|
19
19
|
#
|
20
|
-
# @
|
21
|
-
# Coercions::Rational.call('1/2') #=> (1/2)
|
20
|
+
# @return [Rational] The converted rational number
|
22
21
|
#
|
23
|
-
# @
|
24
|
-
# Coercions::Rational.call(5) #=> (5/1)
|
22
|
+
# @raise [CoercionError] If the value cannot be converted to a rational number
|
25
23
|
#
|
26
|
-
# @example
|
27
|
-
#
|
28
|
-
|
24
|
+
# @example Convert numeric strings to rational numbers
|
25
|
+
# Rational.call("3/4") # => (3/4)
|
26
|
+
# Rational.call("2.5") # => (5/2)
|
27
|
+
# Rational.call("0") # => (0/1)
|
28
|
+
# @example Convert numeric types to rational numbers
|
29
|
+
# Rational.call(3.14) # => (157/50)
|
30
|
+
# Rational.call(2) # => (2/1)
|
31
|
+
# Rational.call(0.5) # => (1/2)
|
32
|
+
# @example Handle edge cases
|
33
|
+
# Rational.call("") # => (0/1)
|
34
|
+
# Rational.call(nil) # => (0/1)
|
35
|
+
# Rational.call(0) # => (0/1)
|
36
|
+
def call(value, options = {})
|
29
37
|
Rational(value)
|
30
|
-
rescue ArgumentError, FloatDomainError, RangeError, TypeError, ZeroDivisionError
|
31
|
-
|
32
|
-
|
33
|
-
type: "rational",
|
34
|
-
default: "could not coerce into a rational"
|
35
|
-
)
|
38
|
+
rescue ArgumentError, FloatDomainError, RangeError, TypeError, ZeroDivisionError
|
39
|
+
type = Locale.t("cmdx.types.rational")
|
40
|
+
raise CoercionError, Locale.t("cmdx.coercions.into_a", type:)
|
36
41
|
end
|
37
42
|
|
38
43
|
end
|
@@ -2,34 +2,31 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Coerces values to String type using Ruby's built-in String() method.
|
6
6
|
#
|
7
|
-
# This coercion handles
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
7
|
+
# This coercion handles various input types by converting them to their
|
8
|
+
# string representation. It's a simple wrapper around Ruby's String()
|
9
|
+
# method for consistency with the CMDx coercion interface.
|
10
|
+
module String
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
# @param _options [Hash] optional configuration (currently unused)
|
16
|
-
#
|
17
|
-
# @return [String] the converted string value
|
12
|
+
extend self
|
13
|
+
|
14
|
+
# Coerces a value to String type.
|
18
15
|
#
|
19
|
-
# @
|
16
|
+
# @param value [Object] The value to coerce to a string
|
17
|
+
# @param options [Hash] Optional configuration parameters (unused in this coercion)
|
20
18
|
#
|
21
|
-
# @
|
22
|
-
# Coercions::String.call(123) #=> "123"
|
23
|
-
# Coercions::String.call(45.67) #=> "45.67"
|
19
|
+
# @return [String] The coerced string value
|
24
20
|
#
|
25
|
-
# @
|
26
|
-
# Coercions::String.call(:symbol) #=> "symbol"
|
27
|
-
# Coercions::String.call(nil) #=> ""
|
21
|
+
# @raise [TypeError] If the value cannot be converted to a string
|
28
22
|
#
|
29
|
-
# @example
|
30
|
-
#
|
31
|
-
#
|
32
|
-
|
23
|
+
# @example Basic string coercion
|
24
|
+
# String.call("hello") # => "hello"
|
25
|
+
# String.call(42) # => "42"
|
26
|
+
# String.call([1, 2, 3]) # => "[1, 2, 3]"
|
27
|
+
# String.call(nil) # => ""
|
28
|
+
# String.call(true) # => "true"
|
29
|
+
def call(value, options = {})
|
33
30
|
String(value)
|
34
31
|
end
|
35
32
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CMDx
|
4
|
+
module Coercions
|
5
|
+
# Coerces values to Symbol type using Ruby's to_sym method.
|
6
|
+
#
|
7
|
+
# This coercion handles various input types by converting them to symbols.
|
8
|
+
# It provides error handling for values that cannot be converted to symbols
|
9
|
+
# and raises appropriate CMDx coercion errors with localized messages.
|
10
|
+
module Symbol
|
11
|
+
|
12
|
+
extend self
|
13
|
+
|
14
|
+
# Coerces a value to Symbol type.
|
15
|
+
#
|
16
|
+
# @param value [Object] The value to coerce to a symbol
|
17
|
+
# @param options [Hash] Optional configuration parameters (unused in this coercion)
|
18
|
+
#
|
19
|
+
# @return [Symbol] The coerced symbol value
|
20
|
+
#
|
21
|
+
# @raise [CoercionError] If the value cannot be converted to a symbol
|
22
|
+
#
|
23
|
+
# @example Basic symbol coercion
|
24
|
+
# Symbol.call("hello") # => :hello
|
25
|
+
# Symbol.call("user_id") # => :user_id
|
26
|
+
# Symbol.call("") # => :""
|
27
|
+
# Symbol.call(:existing) # => :existing
|
28
|
+
def call(value, options = {})
|
29
|
+
value.to_sym
|
30
|
+
rescue NoMethodError
|
31
|
+
type = Locale.t("cmdx.types.symbol")
|
32
|
+
raise CoercionError, Locale.t("cmdx.coercions.into_a", type:)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/cmdx/coercions/time.rb
CHANGED
@@ -2,34 +2,38 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Converts various input types to Time format
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
7
|
+
# Handles conversion from strings, dates, and other time-like objects to Time
|
8
|
+
# using Ruby's built-in time parsing methods. Supports custom strptime formats
|
9
|
+
# and raises CoercionError for values that cannot be converted to Time.
|
10
|
+
module Time
|
11
|
+
|
12
|
+
extend self
|
10
13
|
|
11
14
|
ANALOG_TYPES = %w[DateTime Time].freeze
|
12
15
|
|
13
|
-
# Converts
|
14
|
-
#
|
15
|
-
# @param value [Object] the value to convert to a Time object
|
16
|
-
# @param options [Hash] optional configuration
|
17
|
-
# @option options [String] :strptime custom format string for parsing
|
18
|
-
#
|
19
|
-
# @return [Time] the converted Time object
|
16
|
+
# Converts a value to a Time object
|
20
17
|
#
|
21
|
-
# @
|
18
|
+
# @param value [Object] The value to convert to a Time object
|
19
|
+
# @param options [Hash] Optional configuration parameters
|
20
|
+
# @option options [String] :strptime Custom strptime format string for parsing
|
22
21
|
#
|
23
|
-
# @
|
24
|
-
# Coercions::Time.call('2023-12-25 14:30', strptime: '%Y-%m-%d %H:%M') #=> 2023-12-25 14:30:00
|
22
|
+
# @return [Time] The converted Time object
|
25
23
|
#
|
26
|
-
# @
|
27
|
-
# Coercions::Time.call('2023-12-25 14:30:00') #=> 2023-12-25 14:30:00
|
28
|
-
# Coercions::Time.call('Dec 25, 2023') #=> 2023-12-25 00:00:00
|
24
|
+
# @raise [CoercionError] If the value cannot be converted to a Time object
|
29
25
|
#
|
30
|
-
# @example
|
31
|
-
#
|
32
|
-
#
|
26
|
+
# @example Convert time-like objects
|
27
|
+
# Time.call(Time.now) # => Time object (unchanged)
|
28
|
+
# Time.call(DateTime.now) # => Time object (converted)
|
29
|
+
# Time.call(Date.today) # => Time object (converted)
|
30
|
+
# @example Convert strings with default parsing
|
31
|
+
# Time.call("2023-12-25 10:30:00") # => Time object
|
32
|
+
# Time.call("2023-12-25") # => Time object
|
33
|
+
# Time.call("10:30:00") # => Time object
|
34
|
+
# @example Convert strings with custom format
|
35
|
+
# Time.call("25/12/2023", strptime: "%d/%m/%Y") # => Time object
|
36
|
+
# Time.call("12-25-2023", strptime: "%m-%d-%Y") # => Time object
|
33
37
|
def call(value, options = {})
|
34
38
|
return value if ANALOG_TYPES.include?(value.class.name)
|
35
39
|
return value.to_time if value.respond_to?(:to_time)
|
@@ -37,11 +41,8 @@ module CMDx
|
|
37
41
|
|
38
42
|
::Time.parse(value)
|
39
43
|
rescue ArgumentError, TypeError
|
40
|
-
|
41
|
-
|
42
|
-
type: "time",
|
43
|
-
default: "could not coerce into a time"
|
44
|
-
)
|
44
|
+
type = Locale.t("cmdx.types.time")
|
45
|
+
raise CoercionError, Locale.t("cmdx.coercions.into_a", type:)
|
45
46
|
end
|
46
47
|
|
47
48
|
end
|