cmdx 1.0.0 → 1.1.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/.cursor/prompts/rspec.md +20 -0
- data/.cursor/prompts/yardoc.md +8 -0
- data/.rubocop.yml +5 -0
- data/CHANGELOG.md +101 -49
- data/README.md +2 -1
- data/docs/ai_prompts.md +10 -0
- data/docs/basics/call.md +11 -2
- data/docs/basics/chain.md +10 -1
- data/docs/basics/context.md +9 -0
- data/docs/basics/setup.md +9 -0
- data/docs/callbacks.md +14 -37
- data/docs/configuration.md +68 -27
- data/docs/getting_started.md +11 -0
- data/docs/internationalization.md +148 -0
- data/docs/interruptions/exceptions.md +10 -1
- data/docs/interruptions/faults.md +11 -2
- data/docs/interruptions/halt.md +9 -0
- data/docs/logging.md +14 -4
- data/docs/middlewares.md +53 -43
- data/docs/outcomes/result.md +9 -0
- data/docs/outcomes/states.md +9 -0
- data/docs/outcomes/statuses.md +9 -0
- data/docs/parameters/coercions.md +58 -38
- data/docs/parameters/defaults.md +10 -1
- data/docs/parameters/definitions.md +9 -0
- data/docs/parameters/namespacing.md +9 -0
- data/docs/parameters/validations.md +8 -67
- data/docs/testing.md +22 -13
- data/docs/tips_and_tricks.md +9 -0
- data/docs/workflows.md +14 -4
- data/lib/cmdx/.DS_Store +0 -0
- data/lib/cmdx/callback.rb +36 -56
- data/lib/cmdx/callback_registry.rb +82 -73
- data/lib/cmdx/chain.rb +65 -122
- data/lib/cmdx/chain_inspector.rb +22 -115
- data/lib/cmdx/chain_serializer.rb +17 -148
- data/lib/cmdx/coercion.rb +49 -0
- data/lib/cmdx/coercion_registry.rb +94 -0
- data/lib/cmdx/coercions/array.rb +18 -36
- data/lib/cmdx/coercions/big_decimal.rb +21 -33
- data/lib/cmdx/coercions/boolean.rb +21 -40
- data/lib/cmdx/coercions/complex.rb +18 -31
- data/lib/cmdx/coercions/date.rb +20 -39
- data/lib/cmdx/coercions/date_time.rb +22 -39
- data/lib/cmdx/coercions/float.rb +19 -32
- data/lib/cmdx/coercions/hash.rb +22 -41
- data/lib/cmdx/coercions/integer.rb +20 -33
- data/lib/cmdx/coercions/rational.rb +20 -32
- data/lib/cmdx/coercions/string.rb +23 -31
- data/lib/cmdx/coercions/time.rb +24 -40
- data/lib/cmdx/coercions/virtual.rb +14 -31
- data/lib/cmdx/configuration.rb +57 -171
- data/lib/cmdx/context.rb +22 -165
- data/lib/cmdx/core_ext/hash.rb +42 -67
- data/lib/cmdx/core_ext/module.rb +35 -79
- data/lib/cmdx/core_ext/object.rb +63 -98
- data/lib/cmdx/correlator.rb +40 -156
- data/lib/cmdx/error.rb +37 -202
- data/lib/cmdx/errors.rb +165 -202
- data/lib/cmdx/fault.rb +55 -158
- data/lib/cmdx/faults.rb +26 -137
- data/lib/cmdx/immutator.rb +22 -109
- data/lib/cmdx/lazy_struct.rb +103 -187
- data/lib/cmdx/log_formatters/json.rb +14 -40
- data/lib/cmdx/log_formatters/key_value.rb +14 -40
- data/lib/cmdx/log_formatters/line.rb +14 -48
- data/lib/cmdx/log_formatters/logstash.rb +14 -57
- data/lib/cmdx/log_formatters/pretty_json.rb +14 -50
- data/lib/cmdx/log_formatters/pretty_key_value.rb +13 -46
- data/lib/cmdx/log_formatters/pretty_line.rb +16 -54
- data/lib/cmdx/log_formatters/raw.rb +19 -49
- data/lib/cmdx/logger.rb +20 -82
- data/lib/cmdx/logger_ansi.rb +18 -75
- data/lib/cmdx/logger_serializer.rb +24 -114
- data/lib/cmdx/middleware.rb +38 -60
- data/lib/cmdx/middleware_registry.rb +81 -77
- data/lib/cmdx/middlewares/correlate.rb +41 -226
- data/lib/cmdx/middlewares/timeout.rb +46 -185
- data/lib/cmdx/parameter.rb +120 -198
- data/lib/cmdx/parameter_evaluator.rb +231 -0
- data/lib/cmdx/parameter_inspector.rb +25 -56
- data/lib/cmdx/parameter_registry.rb +59 -84
- data/lib/cmdx/parameter_serializer.rb +23 -74
- data/lib/cmdx/railtie.rb +24 -107
- data/lib/cmdx/result.rb +254 -260
- data/lib/cmdx/result_ansi.rb +19 -85
- data/lib/cmdx/result_inspector.rb +27 -68
- data/lib/cmdx/result_logger.rb +18 -81
- data/lib/cmdx/result_serializer.rb +28 -132
- data/lib/cmdx/rspec/matchers.rb +28 -0
- data/lib/cmdx/rspec/result_matchers/be_executed.rb +42 -0
- data/lib/cmdx/rspec/result_matchers/be_failed_task.rb +94 -0
- data/lib/cmdx/rspec/result_matchers/be_skipped_task.rb +94 -0
- data/lib/cmdx/rspec/result_matchers/be_state_matchers.rb +59 -0
- data/lib/cmdx/rspec/result_matchers/be_status_matchers.rb +57 -0
- data/lib/cmdx/rspec/result_matchers/be_successful_task.rb +87 -0
- data/lib/cmdx/rspec/result_matchers/have_bad_outcome.rb +51 -0
- data/lib/cmdx/rspec/result_matchers/have_caused_failure.rb +58 -0
- data/lib/cmdx/rspec/result_matchers/have_chain_index.rb +59 -0
- data/lib/cmdx/rspec/result_matchers/have_context.rb +86 -0
- data/lib/cmdx/rspec/result_matchers/have_empty_metadata.rb +54 -0
- data/lib/cmdx/rspec/result_matchers/have_good_outcome.rb +52 -0
- data/lib/cmdx/rspec/result_matchers/have_metadata.rb +114 -0
- data/lib/cmdx/rspec/result_matchers/have_preserved_context.rb +66 -0
- data/lib/cmdx/rspec/result_matchers/have_received_thrown_failure.rb +64 -0
- data/lib/cmdx/rspec/result_matchers/have_runtime.rb +78 -0
- data/lib/cmdx/rspec/result_matchers/have_thrown_failure.rb +76 -0
- data/lib/cmdx/rspec/task_matchers/be_well_formed_task.rb +62 -0
- data/lib/cmdx/rspec/task_matchers/have_callback.rb +85 -0
- data/lib/cmdx/rspec/task_matchers/have_cmd_setting.rb +68 -0
- data/lib/cmdx/rspec/task_matchers/have_executed_callbacks.rb +92 -0
- data/lib/cmdx/rspec/task_matchers/have_middleware.rb +46 -0
- data/lib/cmdx/rspec/task_matchers/have_parameter.rb +181 -0
- data/lib/cmdx/task.rb +213 -425
- data/lib/cmdx/task_deprecator.rb +55 -0
- data/lib/cmdx/task_processor.rb +245 -0
- data/lib/cmdx/task_serializer.rb +22 -70
- data/lib/cmdx/utils/ansi_color.rb +13 -89
- data/lib/cmdx/utils/log_timestamp.rb +13 -42
- data/lib/cmdx/utils/monotonic_runtime.rb +13 -63
- data/lib/cmdx/utils/name_affix.rb +21 -71
- data/lib/cmdx/validator.rb +48 -0
- data/lib/cmdx/validator_registry.rb +86 -0
- data/lib/cmdx/validators/exclusion.rb +55 -94
- data/lib/cmdx/validators/format.rb +31 -85
- data/lib/cmdx/validators/inclusion.rb +65 -110
- data/lib/cmdx/validators/length.rb +117 -133
- data/lib/cmdx/validators/numeric.rb +123 -130
- data/lib/cmdx/validators/presence.rb +38 -79
- data/lib/cmdx/version.rb +1 -7
- data/lib/cmdx/workflow.rb +46 -339
- data/lib/cmdx.rb +1 -1
- data/lib/generators/cmdx/install_generator.rb +14 -31
- data/lib/generators/cmdx/task_generator.rb +39 -55
- data/lib/generators/cmdx/templates/install.rb +61 -11
- data/lib/generators/cmdx/workflow_generator.rb +41 -66
- data/lib/locales/ar.yml +35 -0
- data/lib/locales/cs.yml +35 -0
- data/lib/locales/da.yml +35 -0
- data/lib/locales/de.yml +35 -0
- data/lib/locales/el.yml +35 -0
- data/lib/locales/en.yml +19 -20
- data/lib/locales/es.yml +19 -20
- data/lib/locales/fi.yml +35 -0
- data/lib/locales/fr.yml +35 -0
- data/lib/locales/he.yml +35 -0
- data/lib/locales/hi.yml +35 -0
- data/lib/locales/it.yml +35 -0
- data/lib/locales/ja.yml +35 -0
- data/lib/locales/ko.yml +35 -0
- data/lib/locales/nl.yml +35 -0
- data/lib/locales/no.yml +35 -0
- data/lib/locales/pl.yml +35 -0
- data/lib/locales/pt.yml +35 -0
- data/lib/locales/ru.yml +35 -0
- data/lib/locales/sv.yml +35 -0
- data/lib/locales/th.yml +35 -0
- data/lib/locales/tr.yml +35 -0
- data/lib/locales/vi.yml +35 -0
- data/lib/locales/zh.yml +35 -0
- metadata +57 -8
- data/lib/cmdx/parameter_validator.rb +0 -81
- data/lib/cmdx/parameter_value.rb +0 -244
- data/lib/cmdx/parameters_inspector.rb +0 -72
- data/lib/cmdx/parameters_serializer.rb +0 -115
- data/lib/cmdx/rspec/result_matchers.rb +0 -917
- data/lib/cmdx/rspec/task_matchers.rb +0 -570
- data/lib/cmdx/validators/custom.rb +0 -102
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CMDx
|
4
|
+
# Registry for managing type coercion definitions and execution within tasks.
|
5
|
+
#
|
6
|
+
# This registry handles the registration and execution of coercions that convert
|
7
|
+
# parameter values from one type to another, supporting both built-in types and
|
8
|
+
# custom coercion logic.
|
9
|
+
class CoercionRegistry
|
10
|
+
|
11
|
+
# The internal hash storing coercion definitions.
|
12
|
+
#
|
13
|
+
# @return [Hash] hash containing coercion type keys and coercion class/callable values
|
14
|
+
attr_reader :registry
|
15
|
+
|
16
|
+
# Initializes a new coercion registry with default type coercions.
|
17
|
+
#
|
18
|
+
# Sets up the registry with built-in coercions for standard Ruby types
|
19
|
+
# including primitives, numerics, dates, and collections.
|
20
|
+
#
|
21
|
+
# @return [CoercionRegistry] a new coercion registry instance
|
22
|
+
#
|
23
|
+
# @example Creating a new registry
|
24
|
+
# registry = CoercionRegistry.new
|
25
|
+
# registry.registry[:string] # => Coercions::String
|
26
|
+
def initialize
|
27
|
+
@registry = {
|
28
|
+
array: Coercions::Array,
|
29
|
+
big_decimal: Coercions::BigDecimal,
|
30
|
+
boolean: Coercions::Boolean,
|
31
|
+
complex: Coercions::Complex,
|
32
|
+
date: Coercions::Date,
|
33
|
+
datetime: Coercions::DateTime,
|
34
|
+
float: Coercions::Float,
|
35
|
+
hash: Coercions::Hash,
|
36
|
+
integer: Coercions::Integer,
|
37
|
+
rational: Coercions::Rational,
|
38
|
+
string: Coercions::String,
|
39
|
+
time: Coercions::Time,
|
40
|
+
virtual: Coercions::Virtual
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
# Registers a custom coercion for a specific type.
|
45
|
+
#
|
46
|
+
# @param type [Symbol] the type identifier for the coercion
|
47
|
+
# @param coercion [Object] the coercion callable (class, proc, symbol, or string)
|
48
|
+
#
|
49
|
+
# @return [CoercionRegistry] returns self for method chaining
|
50
|
+
#
|
51
|
+
# @example Registering a custom coercion class
|
52
|
+
# registry.register(:uuid, UUIDCoercion)
|
53
|
+
#
|
54
|
+
# @example Registering a proc coercion
|
55
|
+
# registry.register(:upcase, ->(value, options) { value.to_s.upcase })
|
56
|
+
#
|
57
|
+
# @example Chaining registrations
|
58
|
+
# registry.register(:custom1, MyCoercion).register(:custom2, AnotherCoercion)
|
59
|
+
def register(type, coercion)
|
60
|
+
registry[type] = coercion
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
# Executes a coercion for the specified type and value.
|
65
|
+
#
|
66
|
+
# @param task [Task] the task instance executing the coercion
|
67
|
+
# @param type [Symbol] the coercion type to execute
|
68
|
+
# @param value [Object] the value to be coerced
|
69
|
+
# @param options [Hash] additional options for the coercion
|
70
|
+
#
|
71
|
+
# @return [Object] the coerced value
|
72
|
+
#
|
73
|
+
# @raise [UnknownCoercionError] when the coercion type is not registered
|
74
|
+
#
|
75
|
+
# @example Coercing a string to integer
|
76
|
+
# registry.call(task, :integer, "42")
|
77
|
+
# # => 42
|
78
|
+
#
|
79
|
+
# @example Coercing with options
|
80
|
+
# registry.call(task, :array, "a,b,c", delimiter: ",")
|
81
|
+
# # => ["a", "b", "c"]
|
82
|
+
def call(task, type, value, options = {})
|
83
|
+
raise UnknownCoercionError, "unknown coercion #{type}" unless registry.key?(type)
|
84
|
+
|
85
|
+
case coercion = registry[type]
|
86
|
+
when Symbol, String, Proc
|
87
|
+
task.cmdx_try(coercion, value, options)
|
88
|
+
else
|
89
|
+
coercion.call(value, options)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
data/lib/cmdx/coercions/array.rb
CHANGED
@@ -2,47 +2,29 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Coercion class for converting values to arrays.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
10
|
-
#
|
11
|
-
# @example Basic array coercion
|
12
|
-
# class ProcessOrderTask < CMDx::Task
|
13
|
-
# optional :tags, type: :array, default: []
|
14
|
-
# optional :item_ids, type: :array
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# @example Coercion behavior
|
18
|
-
# Coercions::Array.call([1, 2, 3]) # => [1, 2, 3]
|
19
|
-
# Coercions::Array.call("hello") # => ["hello"]
|
20
|
-
# Coercions::Array.call('["a","b"]') # => ["a", "b"] (JSON)
|
21
|
-
# Coercions::Array.call('[1,2,3]') # => [1, 2, 3] (JSON)
|
22
|
-
# Coercions::Array.call(nil) # => []
|
23
|
-
# Coercions::Array.call(42) # => [42]
|
24
|
-
#
|
25
|
-
# @see ParameterValue Parameter value coercion
|
26
|
-
# @see Parameter Parameter type definitions
|
27
|
-
module Array
|
7
|
+
# This coercion handles conversion of various types to arrays, with special
|
8
|
+
# handling for JSON-formatted strings that start with "[".
|
9
|
+
class Array < Coercion
|
28
10
|
|
29
|
-
|
30
|
-
|
31
|
-
#
|
11
|
+
# Converts the given value to an array.
|
12
|
+
#
|
13
|
+
# @param value [Object] the value to convert to an array
|
14
|
+
# @param _options [Hash] optional configuration (currently unused)
|
15
|
+
#
|
16
|
+
# @return [Array] the converted array value
|
32
17
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
# general array conversion.
|
18
|
+
# @raise [JSON::ParserError] if value is a JSON string that cannot be parsed
|
19
|
+
# @raise [TypeError] if the value cannot be converted to an array
|
36
20
|
#
|
37
|
-
# @
|
38
|
-
#
|
39
|
-
# @return [Array] coerced array value
|
40
|
-
# @raise [JSON::ParserError] if JSON parsing fails
|
21
|
+
# @example Converting a JSON string
|
22
|
+
# Coercions::Array.call('["a", "b", "c"]') #=> ["a", "b", "c"]
|
41
23
|
#
|
42
|
-
# @example
|
43
|
-
# Coercions::Array.call("
|
44
|
-
# Coercions::Array.call(
|
45
|
-
# Coercions::Array.call(
|
24
|
+
# @example Converting other values
|
25
|
+
# Coercions::Array.call("hello") #=> ["hello"]
|
26
|
+
# Coercions::Array.call(123) #=> [123]
|
27
|
+
# Coercions::Array.call(nil) #=> []
|
46
28
|
def call(value, _options = {})
|
47
29
|
if value.is_a?(::String) && value.start_with?("[")
|
48
30
|
JSON.parse(value)
|
@@ -2,45 +2,33 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Coercion class for converting values to BigDecimal.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
# and
|
10
|
-
|
11
|
-
# @example Basic BigDecimal coercion
|
12
|
-
# class ProcessOrderTask < CMDx::Task
|
13
|
-
# required :total_amount, type: :big_decimal
|
14
|
-
# optional :tax_rate, type: :big_decimal, precision: 4
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# @example Coercion behavior
|
18
|
-
# Coercions::BigDecimal.call("123.45") # => #<BigDecimal:...,'0.12345E3',18(27)>
|
19
|
-
# Coercions::BigDecimal.call(42) # => #<BigDecimal:...,'0.42E2',9(18)>
|
20
|
-
# Coercions::BigDecimal.call("0.333333", precision: 6) # Custom precision
|
21
|
-
#
|
22
|
-
# @see ParameterValue Parameter value coercion
|
23
|
-
# @see Parameter Parameter type definitions
|
24
|
-
module BigDecimal
|
7
|
+
# This coercion handles conversion of various types to BigDecimal with
|
8
|
+
# configurable precision. It provides precise decimal arithmetic capabilities
|
9
|
+
# for financial calculations and other use cases requiring exact decimal representation.
|
10
|
+
class BigDecimal < Coercion
|
25
11
|
|
26
|
-
# Default precision for BigDecimal calculations
|
27
|
-
# @return [Integer] default precision value
|
28
12
|
DEFAULT_PRECISION = 14
|
29
13
|
|
30
|
-
|
31
|
-
|
32
|
-
#
|
14
|
+
# Converts the given value to a BigDecimal.
|
15
|
+
#
|
16
|
+
# @param value [Object] the value to convert to a BigDecimal
|
17
|
+
# @param options [Hash] optional configuration
|
18
|
+
# @option options [Integer] :precision the precision for the BigDecimal (defaults to 14)
|
19
|
+
#
|
20
|
+
# @return [BigDecimal] the converted BigDecimal value
|
21
|
+
#
|
22
|
+
# @raise [CoercionError] if the value cannot be converted to a BigDecimal
|
23
|
+
#
|
24
|
+
# @example Converting a string
|
25
|
+
# Coercions::BigDecimal.call('123.45') #=> #<BigDecimal:...,'0.12345E3',18(27)>
|
33
26
|
#
|
34
|
-
# @
|
35
|
-
#
|
36
|
-
# @option options [Integer] :precision decimal precision (default: 14)
|
37
|
-
# @return [BigDecimal] coerced BigDecimal value
|
38
|
-
# @raise [CoercionError] if coercion fails
|
27
|
+
# @example Converting with custom precision
|
28
|
+
# Coercions::BigDecimal.call('123.456789', precision: 10) #=> #<BigDecimal:...,'0.123456789E3',18(27)>
|
39
29
|
#
|
40
|
-
# @example
|
41
|
-
# Coercions::BigDecimal.call(
|
42
|
-
# Coercions::BigDecimal.call("0.333", precision: 10) # => BigDecimal with custom precision
|
43
|
-
# Coercions::BigDecimal.call(42.5) # => BigDecimal from float
|
30
|
+
# @example Converting an integer
|
31
|
+
# Coercions::BigDecimal.call(100) #=> #<BigDecimal:...,'0.1E3',9(18)>
|
44
32
|
def call(value, options = {})
|
45
33
|
BigDecimal(value, options[:precision] || DEFAULT_PRECISION)
|
46
34
|
rescue ArgumentError, TypeError
|
@@ -2,53 +2,34 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Coercion class for converting values to booleans.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
11
|
-
# @example Basic boolean coercion
|
12
|
-
# class ProcessOrderTask < CMDx::Task
|
13
|
-
# optional :send_email, type: :boolean, default: true
|
14
|
-
# optional :is_urgent, type: :boolean, default: false
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# @example Coercion behavior
|
18
|
-
# Coercions::Boolean.call("true") # => true
|
19
|
-
# Coercions::Boolean.call("yes") # => true
|
20
|
-
# Coercions::Boolean.call("1") # => true
|
21
|
-
# Coercions::Boolean.call("false") # => false
|
22
|
-
# Coercions::Boolean.call("no") # => false
|
23
|
-
# Coercions::Boolean.call("0") # => false
|
24
|
-
# Coercions::Boolean.call("invalid") # => raises CoercionError
|
25
|
-
#
|
26
|
-
# @see ParameterValue Parameter value coercion
|
27
|
-
# @see Parameter Parameter type definitions
|
28
|
-
module Boolean
|
7
|
+
# This coercion handles conversion of various string representations to
|
8
|
+
# boolean values, supporting common true/false variations like "yes/no",
|
9
|
+
# "1/0", and "t/f".
|
10
|
+
class Boolean < Coercion
|
29
11
|
|
30
|
-
# Pattern matching false-like values (case insensitive)
|
31
|
-
# @return [Regexp] regex for falsey string values
|
32
12
|
FALSEY = /^(false|f|no|n|0)$/i
|
33
|
-
|
34
|
-
# Pattern matching true-like values (case insensitive)
|
35
|
-
# @return [Regexp] regex for truthy string values
|
36
13
|
TRUTHY = /^(true|t|yes|y|1)$/i
|
37
14
|
|
38
|
-
|
39
|
-
|
40
|
-
#
|
15
|
+
# Converts the given value to a boolean.
|
16
|
+
#
|
17
|
+
# @param value [Object] the value to convert to a boolean
|
18
|
+
# @param _options [Hash] optional configuration (currently unused)
|
19
|
+
#
|
20
|
+
# @return [Boolean] the converted boolean value
|
21
|
+
#
|
22
|
+
# @raise [CoercionError] if the value cannot be converted to a boolean
|
41
23
|
#
|
42
|
-
# @
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
24
|
+
# @example Converting truthy values
|
25
|
+
# Coercions::Boolean.call('true') #=> true
|
26
|
+
# Coercions::Boolean.call('yes') #=> true
|
27
|
+
# Coercions::Boolean.call('1') #=> true
|
46
28
|
#
|
47
|
-
# @example
|
48
|
-
# Coercions::Boolean.call(
|
49
|
-
# Coercions::Boolean.call(
|
50
|
-
# Coercions::Boolean.call(
|
51
|
-
# Coercions::Boolean.call("0") # => false
|
29
|
+
# @example Converting falsey values
|
30
|
+
# Coercions::Boolean.call('false') #=> false
|
31
|
+
# Coercions::Boolean.call('no') #=> false
|
32
|
+
# Coercions::Boolean.call('0') #=> false
|
52
33
|
def call(value, _options = {})
|
53
34
|
case value.to_s.downcase
|
54
35
|
when FALSEY then false
|
@@ -2,41 +2,28 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Coercion class for converting values to complex numbers.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
10
|
-
#
|
11
|
-
# @example Basic complex coercion
|
12
|
-
# class MathTask < CMDx::Task
|
13
|
-
# required :complex_number, type: :complex
|
14
|
-
# optional :coefficient, type: :complex, default: Complex(1, 0)
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# @example Coercion behavior
|
18
|
-
# Coercions::Complex.call("1+2i") # => (1+2i)
|
19
|
-
# Coercions::Complex.call("3-4i") # => (3-4i)
|
20
|
-
# Coercions::Complex.call(5) # => (5+0i)
|
21
|
-
# Coercions::Complex.call("invalid") # => raises CoercionError
|
22
|
-
#
|
23
|
-
# @see ParameterValue Parameter value coercion
|
24
|
-
# @see Parameter Parameter type definitions
|
25
|
-
module Complex
|
26
|
-
|
27
|
-
module_function
|
7
|
+
# This coercion handles conversion of various types to complex numbers,
|
8
|
+
# including strings, integers, floats, and other numeric types.
|
9
|
+
class Complex < Coercion
|
28
10
|
|
29
|
-
#
|
11
|
+
# Converts the given value to a complex number.
|
12
|
+
#
|
13
|
+
# @param value [Object] the value to convert to a complex number
|
14
|
+
# @param _options [Hash] optional configuration (currently unused)
|
15
|
+
#
|
16
|
+
# @return [Complex] the converted complex number value
|
17
|
+
#
|
18
|
+
# @raise [CoercionError] if the value cannot be converted to a complex number
|
30
19
|
#
|
31
|
-
# @
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# @raise [CoercionError] if coercion fails
|
20
|
+
# @example Converting numeric values
|
21
|
+
# Coercions::Complex.call(5) #=> (5+0i)
|
22
|
+
# Coercions::Complex.call(3.14) #=> (3.14+0i)
|
35
23
|
#
|
36
|
-
# @example
|
37
|
-
# Coercions::Complex.call("
|
38
|
-
# Coercions::Complex.call(
|
39
|
-
# Coercions::Complex.call("3.5-2i") # => (3.5-2i)
|
24
|
+
# @example Converting string representations
|
25
|
+
# Coercions::Complex.call("2+3i") #=> (2+3i)
|
26
|
+
# Coercions::Complex.call("1-2i") #=> (1-2i)
|
40
27
|
def call(value, _options = {})
|
41
28
|
Complex(value)
|
42
29
|
rescue ArgumentError, TypeError
|
data/lib/cmdx/coercions/date.rb
CHANGED
@@ -2,54 +2,35 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Coercion class for converting values to Date objects.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
10
|
-
#
|
11
|
-
# @example Basic date coercion
|
12
|
-
# class ProcessOrderTask < CMDx::Task
|
13
|
-
# required :order_date, type: :date
|
14
|
-
# optional :delivery_date, type: :date, format: "%Y-%m-%d"
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# @example Coercion behavior
|
18
|
-
# Coercions::Date.call("2023-12-25") # => Date object
|
19
|
-
# Coercions::Date.call("25/12/2023", format: "%d/%m/%Y") # Custom format
|
20
|
-
# Coercions::Date.call(Time.now) # => Date (from Time)
|
21
|
-
# Coercions::Date.call("invalid") # => raises CoercionError
|
22
|
-
#
|
23
|
-
# @see ParameterValue Parameter value coercion
|
24
|
-
# @see Parameter Parameter type definitions
|
25
|
-
module Date
|
7
|
+
# This coercion handles conversion of various types to Date objects, with support
|
8
|
+
# for custom date formats and automatic detection of date-like objects.
|
9
|
+
class Date < Coercion
|
26
10
|
|
27
|
-
# Date-compatible class names that are passed through unchanged
|
28
|
-
# @return [Array<String>] class names that represent date-like objects
|
29
11
|
ANALOG_TYPES = %w[Date DateTime Time].freeze
|
30
12
|
|
31
|
-
|
32
|
-
|
33
|
-
#
|
13
|
+
# Converts the given value to a Date object.
|
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
|
20
|
+
#
|
21
|
+
# @raise [CoercionError] if the value cannot be converted to a Date
|
34
22
|
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# - String with custom format (parsed using strptime)
|
38
|
-
# - String with standard format (parsed using Date.parse)
|
23
|
+
# @example Converting a string with default parsing
|
24
|
+
# Coercions::Date.call('2023-12-25') #=> #<Date: 2023-12-25>
|
39
25
|
#
|
40
|
-
# @
|
41
|
-
#
|
42
|
-
# @option options [String] :format custom date format string
|
43
|
-
# @return [Date] coerced date value
|
44
|
-
# @raise [CoercionError] if coercion fails
|
26
|
+
# @example Converting with custom format
|
27
|
+
# Coercions::Date.call('25/12/2023', strptime: '%d/%m/%Y') #=> #<Date: 2023-12-25>
|
45
28
|
#
|
46
|
-
# @example
|
47
|
-
# Coercions::Date.call(
|
48
|
-
# Coercions::Date.call("25/12/2023", format: "%d/%m/%Y") # => Date with custom format
|
49
|
-
# Coercions::Date.call(Time.now) # => Date from Time
|
29
|
+
# @example Converting existing date-like objects
|
30
|
+
# Coercions::Date.call(DateTime.now) #=> #<Date: 2023-12-25>
|
50
31
|
def call(value, options = {})
|
51
32
|
return value if ANALOG_TYPES.include?(value.class.name)
|
52
|
-
return ::Date.strptime(value, options[:
|
33
|
+
return ::Date.strptime(value, options[:strptime]) if options[:strptime]
|
53
34
|
|
54
35
|
::Date.parse(value)
|
55
36
|
rescue TypeError, ::Date::Error
|
@@ -2,54 +2,37 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Coercion class for converting values to DateTime objects.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
# with support for
|
9
|
-
#
|
10
|
-
|
11
|
-
# @example Basic datetime coercion
|
12
|
-
# class ProcessOrderTask < CMDx::Task
|
13
|
-
# required :order_datetime, type: :date_time
|
14
|
-
# optional :delivery_datetime, type: :date_time, format: "%Y-%m-%d %H:%M:%S"
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# @example Coercion behavior
|
18
|
-
# Coercions::DateTime.call("2023-12-25T14:30:00") # => DateTime object
|
19
|
-
# Coercions::DateTime.call("25/12/2023 2:30 PM", format: "%d/%m/%Y %l:%M %p") # Custom format
|
20
|
-
# Coercions::DateTime.call(Time.now) # => DateTime (from Time)
|
21
|
-
# Coercions::DateTime.call("invalid") # => raises CoercionError
|
22
|
-
#
|
23
|
-
# @see ParameterValue Parameter value coercion
|
24
|
-
# @see Parameter Parameter type definitions
|
25
|
-
module DateTime
|
7
|
+
# This coercion handles conversion of various types to DateTime objects,
|
8
|
+
# with support for custom date/time formats and automatic detection of
|
9
|
+
# analog types (Date, DateTime, Time).
|
10
|
+
class DateTime < Coercion
|
26
11
|
|
27
|
-
# DateTime-compatible class names that are passed through unchanged
|
28
|
-
# @return [Array<String>] class names that represent datetime-like objects
|
29
12
|
ANALOG_TYPES = %w[Date DateTime Time].freeze
|
30
13
|
|
31
|
-
|
32
|
-
|
33
|
-
#
|
14
|
+
# Converts the given value to a DateTime object.
|
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
|
21
|
+
#
|
22
|
+
# @raise [CoercionError] if the value cannot be converted to a DateTime
|
34
23
|
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# - String with custom format (parsed using strptime)
|
38
|
-
# - String with standard format (parsed using DateTime.parse)
|
24
|
+
# @example Converting a date string
|
25
|
+
# Coercions::DateTime.call('2023-12-25') #=> #<DateTime: 2023-12-25T00:00:00+00:00>
|
39
26
|
#
|
40
|
-
# @
|
41
|
-
#
|
42
|
-
# @option options [String] :format custom datetime format string
|
43
|
-
# @return [DateTime] coerced datetime value
|
44
|
-
# @raise [CoercionError] if coercion fails
|
27
|
+
# @example Converting with a custom format
|
28
|
+
# Coercions::DateTime.call('25/12/2023', strptime: '%d/%m/%Y') #=> #<DateTime: 2023-12-25T00:00:00+00:00>
|
45
29
|
#
|
46
|
-
# @example
|
47
|
-
#
|
48
|
-
# Coercions::DateTime.call(
|
49
|
-
# Coercions::DateTime.call(Time.now) # => DateTime from Time
|
30
|
+
# @example Passing through existing DateTime objects
|
31
|
+
# dt = DateTime.now
|
32
|
+
# Coercions::DateTime.call(dt) #=> dt (unchanged)
|
50
33
|
def call(value, options = {})
|
51
34
|
return value if ANALOG_TYPES.include?(value.class.name)
|
52
|
-
return ::DateTime.strptime(value, options[:
|
35
|
+
return ::DateTime.strptime(value, options[:strptime]) if options[:strptime]
|
53
36
|
|
54
37
|
::DateTime.parse(value)
|
55
38
|
rescue TypeError, ::Date::Error
|
data/lib/cmdx/coercions/float.rb
CHANGED
@@ -2,44 +2,31 @@
|
|
2
2
|
|
3
3
|
module CMDx
|
4
4
|
module Coercions
|
5
|
-
#
|
5
|
+
# Coercion class for converting values to floats.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
|
10
|
-
#
|
11
|
-
# @example Basic float coercion
|
12
|
-
# class ProcessOrderTask < CMDx::Task
|
13
|
-
# required :price, type: :float
|
14
|
-
# optional :discount_rate, type: :float, default: 0.0
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# @example Coercion behavior
|
18
|
-
# Coercions::Float.call("123.45") # => 123.45
|
19
|
-
# Coercions::Float.call("1.5e2") # => 150.0 (scientific notation)
|
20
|
-
# Coercions::Float.call(42) # => 42.0
|
21
|
-
# Coercions::Float.call("invalid") # => raises CoercionError
|
22
|
-
#
|
23
|
-
# @see ParameterValue Parameter value coercion
|
24
|
-
# @see Parameter Parameter type definitions
|
25
|
-
module Float
|
26
|
-
|
27
|
-
module_function
|
7
|
+
# This coercion handles conversion of various types to float values using
|
8
|
+
# Ruby's built-in Float() method.
|
9
|
+
class Float < Coercion
|
28
10
|
|
29
|
-
#
|
11
|
+
# Converts the given value to a float.
|
12
|
+
#
|
13
|
+
# @param value [Object] the value to convert to a float
|
14
|
+
# @param _options [Hash] optional configuration (currently unused)
|
15
|
+
#
|
16
|
+
# @return [Float] the converted float value
|
17
|
+
#
|
18
|
+
# @raise [CoercionError] if the value cannot be converted to a float
|
30
19
|
#
|
31
|
-
# @
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# @raise [CoercionError] if coercion fails
|
20
|
+
# @example Converting numeric strings
|
21
|
+
# Coercions::Float.call("3.14") #=> 3.14
|
22
|
+
# Coercions::Float.call("42") #=> 42.0
|
35
23
|
#
|
36
|
-
# @example
|
37
|
-
# Coercions::Float.call(
|
38
|
-
# Coercions::Float.call(
|
39
|
-
# Coercions::Float.call("1e3") # => 1000.0
|
24
|
+
# @example Converting other numeric types
|
25
|
+
# Coercions::Float.call(42) #=> 42.0
|
26
|
+
# Coercions::Float.call(3.14) #=> 3.14
|
40
27
|
def call(value, _options = {})
|
41
28
|
Float(value)
|
42
|
-
rescue ArgumentError, TypeError
|
29
|
+
rescue ArgumentError, RangeError, TypeError
|
43
30
|
raise CoercionError, I18n.t(
|
44
31
|
"cmdx.coercions.into_a",
|
45
32
|
type: "float",
|