Module: AnyVali::Coercion
- Defined in:
- lib/anyvali/parse/coercion.rb
Class Method Summary collapse
- .apply(value, config, kind) ⇒ Object
- .apply_single(value, config, kind) ⇒ Object
-
.coerce_from_string_to_kind(value, kind) ⇒ Object
Map the portable “string” source to the concrete string->kind coercion for the target schema kind.
- .coerce_lower(value) ⇒ Object
- .coerce_string_to_bool(value) ⇒ Object
- .coerce_string_to_int(value) ⇒ Object
- .coerce_string_to_number(value) ⇒ Object
- .coerce_trim(value) ⇒ Object
- .coerce_upper(value) ⇒ Object
Class Method Details
.apply(value, config, kind) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/anyvali/parse/coercion.rb', line 7 def apply(value, config, kind) configs = config.is_a?(Array) ? config : [config] current = value configs.each do |c| result = apply_single(current, c, kind) return result unless result[:success] current = result[:value] end { success: true, value: current } end |
.apply_single(value, config, kind) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/anyvali/parse/coercion.rb', line 20 def apply_single(value, config, kind) case config when "string" # Generic, portable coercion source (spec 5.1). The only portable # source is "string"; infer the target from the schema kind. On a # string-kind schema this is a no-op (the value is already a string). coerce_from_string_to_kind(value, kind) when "string->int" coerce_string_to_int(value) when "string->number" coerce_string_to_number(value) when "string->bool" coerce_string_to_bool(value) when "trim" coerce_trim(value) when "lower" coerce_lower(value) when "upper" coerce_upper(value) else { success: false, value: value } end end |
.coerce_from_string_to_kind(value, kind) ⇒ Object
Map the portable “string” source to the concrete string->kind coercion for the target schema kind. Integer family -> int; float family -> number; bool -> bool; everything else (string/unknown/…) is a no-op.
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/anyvali/parse/coercion.rb', line 47 def coerce_from_string_to_kind(value, kind) case kind when "int", "int8", "int16", "int32", "int64", "uint8", "uint16", "uint32", "uint64" coerce_string_to_int(value) when "number", "float32", "float64" coerce_string_to_number(value) when "bool" coerce_string_to_bool(value) else { success: true, value: value } end end |
.coerce_lower(value) ⇒ Object
110 111 112 113 |
# File 'lib/anyvali/parse/coercion.rb', line 110 def coerce_lower(value) return { success: true, value: value } unless value.is_a?(String) { success: true, value: value.downcase } end |
.coerce_string_to_bool(value) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/anyvali/parse/coercion.rb', line 91 def coerce_string_to_bool(value) return { success: true, value: value } if value.is_a?(TrueClass) || value.is_a?(FalseClass) return { success: false, value: value } unless value.is_a?(String) case value.strip.downcase when "true", "1" { success: true, value: true } when "false", "0" { success: true, value: false } else { success: false, value: value } end end |
.coerce_string_to_int(value) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/anyvali/parse/coercion.rb', line 61 def coerce_string_to_int(value) return { success: true, value: value } if value.is_a?(Integer) return { success: false, value: value } unless value.is_a?(String) stripped = value.strip if stripped.match?(/\A-?\d+\z/) { success: true, value: stripped.to_i } else { success: false, value: value } end end |
.coerce_string_to_number(value) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/anyvali/parse/coercion.rb', line 73 def coerce_string_to_number(value) return { success: true, value: value } if value.is_a?(Numeric) return { success: false, value: value } unless value.is_a?(String) stripped = value.strip # Spec 5.1: parse DECIMAL floating-point only. Ruby's Float() also accepts # digit-group underscores ("1_000.5") and hex floats ("0x1.8p3"), which # diverge from the JS reference and let non-decimal strings slip through. return { success: false, value: value } unless stripped.match?(/\A[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?\z/) begin f = Float(stripped) { success: true, value: f } rescue ArgumentError { success: false, value: value } end end |
.coerce_trim(value) ⇒ Object
105 106 107 108 |
# File 'lib/anyvali/parse/coercion.rb', line 105 def coerce_trim(value) return { success: true, value: value } unless value.is_a?(String) { success: true, value: value.strip } end |
.coerce_upper(value) ⇒ Object
115 116 117 118 |
# File 'lib/anyvali/parse/coercion.rb', line 115 def coerce_upper(value) return { success: true, value: value } unless value.is_a?(String) { success: true, value: value.upcase } end |