lib/thrift/struct.rb in thrift-0.2.0.4 vs lib/thrift/struct.rb in thrift-0.4.0

- old
+ new

@@ -63,37 +63,18 @@ end self.class.instance_variable_set("@fields_with_default_values", fields_with_default_values) end fields_with_default_values end - - def name_to_id(name) - names_to_ids = self.class.instance_variable_get("@names_to_ids") - unless names_to_ids - names_to_ids = {} - struct_fields.each do |fid, field_def| - names_to_ids[field_def[:name]] = fid - end - self.class.instance_variable_set("@names_to_ids", names_to_ids) - end - names_to_ids[name] - end - - def each_field - struct_fields.keys.sort.each do |fid| - data = struct_fields[fid] - yield fid, data - end - end - + def inspect(skip_optional_nulls = true) fields = [] each_field do |fid, field_info| name = field_info[:name] value = instance_variable_get("@#{name}") unless skip_optional_nulls && field_info[:optional] && value.nil? - fields << "#{name}:#{value.inspect}" + fields << "#{name}:#{inspect_field(value, field_info)}" end end "<#{self.class} #{fields.join(", ")}>" end @@ -113,11 +94,12 @@ validate oprot.write_struct_begin(self.class.name) each_field do |fid, field_info| name = field_info[:name] type = field_info[:type] - if (value = instance_variable_get("@#{name}")) + value = instance_variable_get("@#{name}") + unless value.nil? if is_container? type oprot.write_field_begin(name, type, fid) write_container(oprot, value, field_info) oprot.write_field_end else @@ -161,17 +143,53 @@ end end diffs end - def self.field_accessor(klass, *fields) - fields.each do |field| - klass.send :attr_reader, field - klass.send :define_method, "#{field}=" do |value| - Thrift.check_type(value, klass::FIELDS.values.find { |f| f[:name].to_s == field.to_s }, field) if Thrift.type_checking - instance_variable_set("@#{field}", value) + def self.field_accessor(klass, field_info) + field_name_sym = field_info[:name].to_sym + klass.send :attr_reader, field_name_sym + klass.send :define_method, "#{field_info[:name]}=" do |value| + Thrift.check_type(value, field_info, field_info[:name]) if Thrift.type_checking + instance_variable_set("@#{field_name_sym}", value) + end + end + + def self.generate_accessors(klass) + klass::FIELDS.values.each do |field_info| + field_accessor(klass, field_info) + qmark_isset_method(klass, field_info) + end + end + + def self.qmark_isset_method(klass, field_info) + klass.send :define_method, "#{field_info[:name]}?" do + !self.send(field_info[:name].to_sym).nil? + end + end + + def <=>(other) + if self.class == other.class + each_field do |fid, field_info| + v1 = self.send(field_info[:name]) + v1_set = !v1.nil? + v2 = other.send(field_info[:name]) + v2_set = !v2.nil? + if v1_set && !v2_set + return -1 + elsif !v1_set && v2_set + return 1 + elsif v1_set && v2_set + cmp = v1 <=> v2 + if cmp != 0 + return cmp + end + end end + 0 + else + self.class <=> other.class end end protected @@ -207,92 +225,8 @@ value = read_field(iprot, field) instance_variable_set("@#{field[:name]}", value) else iprot.skip(ftype) end - end - - def read_field(iprot, field = {}) - case field[:type] - when Types::STRUCT - value = field[:class].new - value.read(iprot) - when Types::MAP - key_type, val_type, size = iprot.read_map_begin - value = {} - size.times do - k = read_field(iprot, field_info(field[:key])) - v = read_field(iprot, field_info(field[:value])) - value[k] = v - end - iprot.read_map_end - when Types::LIST - e_type, size = iprot.read_list_begin - value = Array.new(size) do |n| - read_field(iprot, field_info(field[:element])) - end - iprot.read_list_end - when Types::SET - e_type, size = iprot.read_set_begin - value = Set.new - size.times do - element = read_field(iprot, field_info(field[:element])) - value << element - end - iprot.read_set_end - else - value = iprot.read_type(field[:type]) - end - value - end - - def write_data(oprot, value, field) - if is_container? field[:type] - write_container(oprot, value, field) - else - oprot.write_type(field[:type], value) - end - end - - def write_container(oprot, value, field = {}) - case field[:type] - when Types::MAP - oprot.write_map_begin(field[:key][:type], field[:value][:type], value.size) - value.each do |k, v| - write_data(oprot, k, field[:key]) - write_data(oprot, v, field[:value]) - end - oprot.write_map_end - when Types::LIST - oprot.write_list_begin(field[:element][:type], value.size) - value.each do |elem| - write_data(oprot, elem, field[:element]) - end - oprot.write_list_end - when Types::SET - oprot.write_set_begin(field[:element][:type], value.size) - value.each do |v,| # the , is to preserve compatibility with the old Hash-style sets - write_data(oprot, v, field[:element]) - end - oprot.write_set_end - else - raise "Not a container type: #{field[:type]}" - end - end - - CONTAINER_TYPES = [] - CONTAINER_TYPES[Types::LIST] = true - CONTAINER_TYPES[Types::MAP] = true - CONTAINER_TYPES[Types::SET] = true - def is_container?(type) - CONTAINER_TYPES[type] - end - - def field_info(field) - { :type => field[:type], - :class => field[:class], - :key => field[:key], - :value => field[:value], - :element => field[:element] } end end end