Module: Decoding::Decoders

Defined in:
lib/decoding/decoders.rb,
lib/decoding/decoders/at.rb,
lib/decoding/decoders/any.rb,
lib/decoding/decoders/map.rb,
lib/decoding/decoders/hash.rb,
lib/decoding/decoders/pass.rb,
lib/decoding/decoders/array.rb,
lib/decoding/decoders/field.rb,
lib/decoding/decoders/index.rb,
lib/decoding/decoders/match.rb,
lib/decoding/decoders/and_then.rb

Overview

Decoders are composable functions for deconstructing unknown input values into known output values.

Defined Under Namespace

Classes: AndThen, Any, Array, At, Field, Hash, Index, Map, Match, Pass

Simple decoders collapse

Utility decoders collapse

Compound decoders collapse

Class Method Details

.and_then(deocder) {|value| ... } ⇒ Decoding::Decoder<b>

Create a decoder that depends on a previously decoded value.

Examples:

decoder = and_then(field("version", integer)) do |version|
  if version == 1
    field("name", string)
  else
    field("fullName", string)
  end
end
decode(decoder, { "version" => 1, "name" => "john" })
# => Decoding::Ok("john")
decode(decoder, { "version" => 2, "fullName" => "john" })
# => Decoding::Ok("john")

Parameters:

Yield Parameters:

  • value (a)

Yield Returns:

Returns:

See Also:



259
# File 'lib/decoding/decoders.rb', line 259

def and_then(...) = Decoders::AndThen.new(...)

.any(decoder, *decoders) ⇒ Decoding::Decoder<a>

Decode a value by trying many different decoders in order, using the first matching result -- or a failure when none of the given decoders succeed.

Examples:

decode(any(string, integer), 12) # => Decoding::Ok(12)
decode(any(string, integer), '12') # => Decoding::Ok('12')

Parameters:

Returns:

See Also:



162
# File 'lib/decoding/decoders.rb', line 162

def any(...) = Decoders::Any.new(...)

.array(decoder) ⇒ Decoding::Decoder<Array<a>>

Decode an array of values using a given decoder.

Examples:

decode(array(integer), [1, 2, 3]) # => Decoding::Ok([1, 2, 3])

Parameters:

Returns:

See Also:



192
# File 'lib/decoding/decoders.rb', line 192

def array(...) = Decoders::Array.new(...)

.at(*fields, decoder) ⇒ Decoding::Decoder<a>

Decode deeply-nested fields.

Examples:

decoder = at('a', 'b', 'c', string)
decode(decoder, { "a" => { "b" => { "c" => "d" } } })
# => Decoding::Ok("d")
decode(decoder, { "a" => { "b" => "d" } })
# => Decoding::Err("Error at .a.b: expected a Hash, got String")

Parameters:

Returns:

See Also:



274
275
276
# File 'lib/decoding/decoders.rb', line 274

def at(...)
  Decoders::At.new(...)
end

.booleanDecoding::Decoder<Boolean>

Decode a boolean value (either true or false).

Examples:

decode(boolean, true) # => Decoding::Ok(true)
decode(boolean, false) # => Decoding::Ok(false)

Returns:



93
# File 'lib/decoding/decoders.rb', line 93

def boolean = any(self.true, self.false)

.decode_hash(decoders) ⇒ Object

Decode a value into a hash using multiple decoders.

This is a shortcut for:

deocde(map(field("id", integer), field("name", string)) { |id, name| { id:, name: } }, { "id" => 1, "name" => "John" }) # => Decoding::Ok({ id: 1, name: "John" })

Examples:

decode(decode_hash(
  id: field("id", integer)
), { "id" => 1 })
# => Decode::Ok({ id: 1 })

Returns:

  • Decoding::Decoder



233
234
235
236
237
# File 'lib/decoding/decoders.rb', line 233

def decode_hash(decoders)
  map(*decoders.values) do |*values|
    decoders.keys.zip(values).to_h
  end
end

.fail(value) ⇒ Decoding::Decoder<String>

A decoder that always fails with the given value.

Examples:

decode(fail("oh no"), "foo") # => Decoding::Err("oh no")

Returns:



116
# File 'lib/decoding/decoders.rb', line 116

def fail(value) = ->(_) { Result.err(Decoding::Failure.new(value)) }

.falseDecoding::Decoder<FalseClass>

Decode a false value.

Examples:

decode(Decoders.false, false) # => Decoding::Ok(false)

Returns:

See Also:



85
# File 'lib/decoding/decoders.rb', line 85

def false = Decoders::Match.new(FalseClass)

.field(key, decoder) ⇒ Decoding::Decoder<a>

Decode a value from a given key in a hash.

Examples:

decode(field('id', integer), { 'id' => 5 }) # => Decoding::Ok(5)

Parameters:

Returns:

See Also:



182
# File 'lib/decoding/decoders.rb', line 182

def field(...) = Decoders::Field.new(...)

.floatDecoding::Decoder<Float>

Decode any float value.

Examples:

decode(float, 0.5) # => Decoding::Ok(0.5)

Returns:

See Also:



52
# File 'lib/decoding/decoders.rb', line 52

def float = Decoders::Match.new(Float)

.hash(key_decoder, value_decoder) ⇒ Decoding::Decoder<Hash<a, b>>

Decode a Hash with arbitrary contents using two decoders for the keys and the pairs.

Examples:

decode(hash(string, integer), { 'john' => 1 })
# => Decoding::Ok({ 'john' => 1 })

Parameters:

Returns:

See Also:



216
# File 'lib/decoding/decoders.rb', line 216

def hash(...) = Decoders::Hash.new(...)

.index(integer, decoder) ⇒ Decoding::Decoder<a>

Decode an array element by index using a given decoder.

Examples:

decode(index(0, integer), [1, 2, 3]) # => Decoding::Ok(1)

Parameters:

Returns:

See Also:



203
# File 'lib/decoding/decoders.rb', line 203

def index(...) = Decoders::Index.new(...)

.integerDecoding::Decoder<Integer>

Decode any integer value.

Examples:

decode(integer, 1) # => Decoding::Ok(1)

Returns:

See Also:



44
# File 'lib/decoding/decoders.rb', line 44

def integer = Decoders::Match.new(Integer)

.map(decoder, *decoders) {|value| ... } ⇒ Decoding::Decoder<b>

Decode a value with the given decoder and, if successful, apply a block to the decoded result.

Given multiple decoders, apply them all to the same value and, if all succeeded, create a single output value from them.

Examples:

map over a single value

decode(map(string, &:upcase), "foo") # => Decoding::Ok("FOO")

map over multiple values

decode(
  map(
    field("id", integer),
    field("name", string)
  ) { |id, name| [id, name] },
  { "id" => 1, "name" => "john" }
)
# => [1, "john"]

Parameters:

Yield Parameters:

  • value (a)

Yield Returns:

  • (b)

Returns:

See Also:



150
# File 'lib/decoding/decoders.rb', line 150

def map(...) = Decoders::Map.new(...)

.nilDecoding::Decoder<NilClass>

Decode a nil value.

Examples:

decode(Decoders.nil, nil) # => Decoding::Ok(nil)

Returns:

See Also:



69
# File 'lib/decoding/decoders.rb', line 69

def nil = Decoders::Match.new(NilClass)

.numericDecoding::Decoder<Numeric>

Decode any numeric value (includes both integers and floats).

Examples:

decode(numeric, 1) # => Decoding::Ok(1)
decode(numeric, 1.5) # => Decoding::Ok(1.5)

Returns:

See Also:



61
# File 'lib/decoding/decoders.rb', line 61

def numeric = Decoders::Match.new(Numeric)

.optional(decoder) ⇒ Decoding::Decoder<a, nil>

Decode a value that may or may not be nil.

Examples:

decode(string, "foo") # => Decoding::Ok("foo")
decode(string, nil) # => Decoding::Ok(nil)

Parameters:

Returns:



171
# File 'lib/decoding/decoders.rb', line 171

def optional(decoder) = any(decoder, self.nil)

.originalDecoding::Decoder<Object>

A decoder that returns the input value, unaltered.

Examples:

decode(original, [1, 2]) # => Decoding::Ok([1, 2])

Returns:



123
# File 'lib/decoding/decoders.rb', line 123

def original = Decoders::Pass.new

.regexp(regex) ⇒ Decoding::Decoder<String>

Decode any string value that matches a regular expression.

Parameters:

  • re (Regexp, String)

Returns:

See Also:



36
# File 'lib/decoding/decoders.rb', line 36

def regexp(regex) = Decoders::Match.new(Regexp.new(regex))

.stringDecoding::Decoder<String>

Decode any string value.

Examples:

decode(string, "foo") # => Decoding::Ok("foo")

Returns:

See Also:



29
# File 'lib/decoding/decoders.rb', line 29

def string = Decoders::Match.new(String)

.succeed(value) ⇒ Decoding::Decoder<String>

A decoder that always succeeds with the given value.

Examples:

decode(succeed(5), "foo") # => Decoding::Ok(5)

Returns:



109
# File 'lib/decoding/decoders.rb', line 109

def succeed(value) = ->(_) { Result.ok(value) }

.symbolDecoding::Decoder<Symbol>

Decode a String value into a symbol.

Examples:

decode(symbol, "foo") # => Decoding::Ok(:foo)

Returns:



100
# File 'lib/decoding/decoders.rb', line 100

def symbol = map(string, &:to_sym)

.trueDecoding::Decoder<TrueClass>

Decode a true value.

Examples:

decode(Decoding.true, true) # => Decoding::Ok(true)

Returns:

See Also:



77
# File 'lib/decoding/decoders.rb', line 77

def true = Decoders::Match.new(TrueClass)