Module: Beefcake::Message::Encode

Defined in:
lib/beefcake.rb

Instance Method Summary collapse

Instance Method Details

#encode(buf = Buffer.new) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/beefcake.rb', line 59

def encode(buf = Buffer.new)
  validate!

  if ! buf.respond_to?(:<<)
    raise ArgumentError, "buf doesn't respond to `<<`"
  end

  if ! buf.is_a?(Buffer)
    buf = Buffer.new(buf)
  end

  # TODO: Error if any required fields at nil

  fields.values.sort.each do |fld|
    if fld.opts[:packed]
      bytes = encode!(Buffer.new, fld, 0)
      buf.append_info(fld.fn, Buffer.wire_for(fld.type))
      buf.append_uint64(bytes.length)
      buf << bytes
    else
      encode!(buf, fld, fld.fn)
    end
  end

  buf
end

#encode!(buf, fld, fn) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/beefcake.rb', line 86

def encode!(buf, fld, fn)
  v = self[fld.name]
  v = v.is_a?(Array) ? v : [v]

  v.compact.each do |val|
    case fld.type
    when Class # encodable
      # TODO: raise error if type != val.class
      buf.append(:string, val.encode, fn)
    when Module # enum
      if ! valid_enum?(fld.type, val)
        raise InvalidValueError.new(fld.name, val)
      end

      buf.append(:int32, val, fn)
    else
      buf.append(fld.type, val, fn)
    end
  end

  buf
end

#name_for(mod, val) ⇒ Object



113
114
115
116
117
118
119
120
# File 'lib/beefcake.rb', line 113

def name_for(mod, val)
  mod.constants.each do |name|
    if mod.const_get(name) == val
      return name
    end
  end
  nil
end

#valid_enum?(mod, val) ⇒ Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/beefcake.rb', line 109

def valid_enum?(mod, val)
  !!name_for(mod, val)
end

#validate!Object



122
123
124
125
126
127
128
# File 'lib/beefcake.rb', line 122

def validate!
  fields.values.each do |fld|
    if fld.rule == :required && self[fld.name].nil?
      raise RequiredFieldNotSetError, fld.name
    end
  end
end