Module: Arf::Types

Defined in:
lib/arf/types.rb,
lib/arf/types/mixin.rb,
lib/arf/types/coercion.rb,
lib/arf/types/map_type.rb,
lib/arf/types/streamer.rb,
lib/arf/types/base_type.rb,
lib/arf/types/array_type.rb,
lib/arf/types/input_stream.rb,
lib/arf/types/in_out_stream.rb,
lib/arf/types/output_stream.rb

Defined Under Namespace

Modules: Mixin Classes: ArrayType, BaseType, InOutStream, InputStream, MapType, OutputStream, Streamer

Constant Summary collapse

INTEGERS =
%i[uint8 uint16 uint32 uint64 int8 int16 int32 int64].freeze
FLOATS =
%i[float32 float64].freeze
OTHERS =
%i[bool string bytes].freeze

Class Method Summary collapse

Class Method Details

.coerce_value(value, type) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/arf/types/coercion.rb', line 5

def self.coerce_value(value, type)
  if Types::INTEGERS.include?(type)
    value.to_i
  elsif Types::FLOATS.include?(type)
    value.to_f
  elsif type == :string
    value.to_s
  elsif type == :bytes
    case value
    when StringIO then value.string
    when String then value
    when Array then value.pack("C*")
    else
      raise ArgumentError, "Invalid type for bytes: #{i.class.name}"
    end
  elsif type == :bool
    !!value
  elsif type.is_a?(Class)
    case value
    when Hash then type.new(**value)
    when type then value
    else
      raise ArgumentError,
            "Cannot initialize #{type} with #{value.inspect} (#{value.class}). " \
            "You may want to use an instance of #{type}, or a Hash"
    end
  elsif type.is_a?(Arf::Types::ArrayType) || type.is_a?(Arf::Types::MapType)
    type.coerce(value)
  end
end

.lookup_type(mod, path, direction:) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/arf/types.rb', line 25

def self.lookup_type(mod, path, direction:)
  key = [mod, path.join("::"), direction]
  @lookup_cache ||= {}
  return @lookup_cache[key] if @lookup_cache.key? key

  v = if direction == :up
        lookup_type_up(mod, path)
      else
        lookup_type_down(mod, path)
      end

  @lookup_cache[key] = v
end

.lookup_type_down(mod, path) ⇒ Object



59
60
61
62
63
64
65
66
67
# File 'lib/arf/types.rb', line 59

def self.lookup_type_down(mod, path)
  return mod if path.empty?

  key = path.first
  v = try_const_get(mod, key)
  return nil unless v

  lookup_type_down(v, path.tap(&:shift))
end

.lookup_type_up(mod, path) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/arf/types.rb', line 39

def self.lookup_type_up(mod, path)
  return mod if path.empty?

  key = path.first
  v = try_const_get(mod, key)
  if v
    lookup_type_down(v, path.tap(&:shift))
  elsif mod == Object
    nil
  else
    parent = mod.name.split("::").tap(&:pop).last
    return nil if parent.nil?

    v = try_const_get(mod, parent)
    return nil if v.nil?

    lookup_type_down(v, path)
  end
end

.try_const_get(mod, name) ⇒ Object



19
20
21
22
23
# File 'lib/arf/types.rb', line 19

def self.try_const_get(mod, name)
  mod.const_get(name)
rescue NameError
  nil
end