Class: CMDx::Coercions
- Inherits:
-
Object
- Object
- CMDx::Coercions
- Defined in:
- lib/cmdx/coercions.rb,
lib/cmdx/coercions/date.rb,
lib/cmdx/coercions/hash.rb,
lib/cmdx/coercions/time.rb,
lib/cmdx/coercions/array.rb,
lib/cmdx/coercions/float.rb,
lib/cmdx/coercions/coerce.rb,
lib/cmdx/coercions/string.rb,
lib/cmdx/coercions/symbol.rb,
lib/cmdx/coercions/boolean.rb,
lib/cmdx/coercions/complex.rb,
lib/cmdx/coercions/integer.rb,
lib/cmdx/coercions/rational.rb,
lib/cmdx/coercions/date_time.rb,
lib/cmdx/coercions/big_decimal.rb
Overview
Registry of named type coercions applied to input/output values. Ships with built-ins for ‘:array`, `:big_decimal`, `:boolean`, `:complex`, `:date`, `:date_time`, `:float`, `:hash`, `:integer`, `:rational`, `:string`, `:symbol`, `:time`. Coercion handlers return the coerced value on success, or a Failure carrying an i18n message on failure.
Defined Under Namespace
Modules: Array, BigDecimal, Boolean, Coerce, Complex, Date, DateTime, Float, Hash, Integer, Rational, String, Symbol, Time Classes: Failure
Instance Attribute Summary collapse
-
#registry ⇒ Object
readonly
Returns the value of attribute registry.
Instance Method Summary collapse
-
#coerce(task, name, value, rules) ⇒ Object, Failure
Applies each coercion rule to ‘value`.
-
#deregister(name) ⇒ Coercions
Self for chaining.
- #empty? ⇒ Boolean
-
#extract(options) ⇒ Array<Array(Object, Hash)>
Normalizes the ‘:coerce` declaration on an input/output into a list of `[handler, opts]` pairs.
-
#initialize ⇒ Coercions
constructor
A new instance of Coercions.
- #initialize_copy(source) ⇒ void
-
#key?(name) ⇒ Boolean
Whether a coercion is registered under ‘name`.
-
#lookup(name) ⇒ #call
The registered coercion.
-
#register(name, callable = nil, &block) {|see built-in coercion signatures — `call(value, options = {})`| ... } ⇒ Coercions
Registers a named coercion, overwriting any existing entry with the same name.
- #size ⇒ Integer
Constructor Details
#initialize ⇒ Coercions
Returns a new instance of Coercions.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/cmdx/coercions.rb', line 17 def initialize @registry = { array: Coercions::Array, big_decimal: Coercions::BigDecimal, boolean: Coercions::Boolean, complex: Coercions::Complex, date: Coercions::Date, date_time: Coercions::DateTime, float: Coercions::Float, hash: Coercions::Hash, integer: Coercions::Integer, rational: Coercions::Rational, string: Coercions::String, symbol: Coercions::Symbol, time: Coercions::Time } end |
Instance Attribute Details
#registry ⇒ Object (readonly)
Returns the value of attribute registry.
15 16 17 |
# File 'lib/cmdx/coercions.rb', line 15 def registry @registry end |
Instance Method Details
#coerce(task, name, value, rules) ⇒ Object, Failure
Applies each coercion rule to ‘value`. Returns the first successful coercion. When every rule fails and more than one was declared (and none were inline callables), the aggregated “into_any” message is recorded; otherwise the last individual failure is used.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/cmdx/coercions.rb', line 143 def coerce(task, name, value, rules) return value if rules.empty? last_failure = nil any_inline = false rules.each do |handler, opts| result = if handler.is_a?(::Symbol) && registry.key?(handler) lookup(handler).call(value, **opts) else any_inline = true Coercions::Coerce.call(task, value, handler) end return result unless result.is_a?(Failure) last_failure = result end if rules.size > 1 && !any_inline type_names = rules.map { |h, _| I18nProxy.t("cmdx.types.#{h}") }.join(", ") last_failure = Failure.new(I18nProxy.t("cmdx.coercions.into_any", types: type_names)) end task.errors.add(name, last_failure.) last_failure end |
#deregister(name) ⇒ Coercions
Returns self for chaining.
69 70 71 72 |
# File 'lib/cmdx/coercions.rb', line 69 def deregister(name) registry.delete(name) self end |
#empty? ⇒ Boolean
124 125 126 |
# File 'lib/cmdx/coercions.rb', line 124 def empty? registry.empty? end |
#extract(options) ⇒ Array<Array(Object, Hash)>
Normalizes the ‘:coerce` declaration on an input/output into a list of `[handler, opts]` pairs. Accepts a Symbol, Array, Hash, or any callable.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/cmdx/coercions.rb', line 100 def extract() return EMPTY_ARRAY if .empty? raw = [:coerce] return EMPTY_ARRAY if raw.nil? || raw == EMPTY_ARRAY case raw when ::Symbol [[raw, EMPTY_HASH]] when ::Array raw.map { |t| normalize_entry(t) } when ::Hash raw.map { |k, v| [k, v == true ? EMPTY_HASH : v] } else return [[raw, EMPTY_HASH]] if raw.respond_to?(:call) raise ArgumentError, <<~MSG.chomp unsupported :coerce format #{raw.inspect}; expected Symbol, Array, Hash, or a callable. See https://drexed.github.io/cmdx/inputs/coercions/#declarations MSG end end |
#initialize_copy(source) ⇒ void
This method returns an undefined value.
37 38 39 |
# File 'lib/cmdx/coercions.rb', line 37 def initialize_copy(source) @registry = source.registry.dup end |
#key?(name) ⇒ Boolean
Returns whether a coercion is registered under ‘name`.
76 77 78 |
# File 'lib/cmdx/coercions.rb', line 76 def key?(name) registry.key?(name) end |
#lookup(name) ⇒ #call
Returns the registered coercion.
83 84 85 86 87 88 89 90 |
# File 'lib/cmdx/coercions.rb', line 83 def lookup(name) registry[name] || begin raise UnknownEntryError, <<~MSG.chomp unknown coercion #{name.inspect}; registered: #{registry.keys.inspect}. See https://drexed.github.io/cmdx/inputs/coercions/#built-in-coercions MSG end end |
#register(name, callable = nil, &block) {|see built-in coercion signatures — `call(value, options = {})`| ... } ⇒ Coercions
Registers a named coercion, overwriting any existing entry with the same name.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/cmdx/coercions.rb', line 51 def register(name, callable = nil, &block) coercion = callable || block if callable && block raise ArgumentError, "coercion: provide either a callable or a block, not both" elsif !coercion.respond_to?(:call) raise ArgumentError, <<~MSG.chomp coercion must respond to #call (got #{coercion.class}). See https://drexed.github.io/cmdx/inputs/coercions/#declarations MSG end registry[name.to_sym] = coercion self end |