lib/thrift/struct.rb in thrift-0.0.751142 vs lib/thrift/struct.rb in thrift-0.0.810255.1
- old
+ new
@@ -1,6 +1,24 @@
-require 'thrift/types'
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
require 'set'
module Thrift
module Struct
def initialize(d={})
@@ -37,11 +55,11 @@
def fields_with_default_values
fields_with_default_values = self.class.instance_variable_get("@fields_with_default_values")
unless fields_with_default_values
fields_with_default_values = {}
struct_fields.each do |fid, field_def|
- if field_def[:default]
+ unless field_def[:default].nil?
fields_with_default_values[field_def[:name]] = field_def[:default]
end
end
self.class.instance_variable_set("@fields_with_default_values", fields_with_default_values)
end
@@ -58,90 +76,95 @@
self.class.instance_variable_set("@names_to_ids", names_to_ids)
end
names_to_ids[name]
end
- # Obsoleted by THRIFT-246, which generates this method inline
- # TODO: Should be removed at some point. -- Kevin Clark
- def struct_fields
- self.class.const_get(:FIELDS)
- end
-
def each_field
- struct_fields.each do |fid, data|
- yield fid, data[:type], data[:name], data[:default], data[:optional]
+ 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, type, name, default, optional|
+ each_field do |fid, field_info|
+ name = field_info[:name]
value = instance_variable_get("@#{name}")
- unless skip_optional_nulls && optional && value.nil?
+ unless skip_optional_nulls && field_info[:optional] && value.nil?
fields << "#{name}:#{value.inspect}"
end
end
"<#{self.class} #{fields.join(", ")}>"
end
def read(iprot)
- # TODO(kevinclark): Make sure transport is C readable
- if iprot.respond_to?(:decode_binary)
- iprot.decode_binary(self, iprot.trans)
- else
- iprot.read_struct_begin
- loop do
- fname, ftype, fid = iprot.read_field_begin
- break if (ftype == Types::STOP)
- handle_message(iprot, fid, ftype)
- iprot.read_field_end
- end
- iprot.read_struct_end
+ iprot.read_struct_begin
+ loop do
+ fname, ftype, fid = iprot.read_field_begin
+ break if (ftype == Types::STOP)
+ handle_message(iprot, fid, ftype)
+ iprot.read_field_end
end
+ iprot.read_struct_end
validate
end
def write(oprot)
validate
- # if oprot.respond_to?(:encode_binary)
- # # TODO(kevinclark): Clean this so I don't have to access the transport.
- # oprot.trans.write oprot.encode_binary(self)
- # else
- oprot.write_struct_begin(self.class.name)
- each_field do |fid, type, name|
- unless (value = instance_variable_get("@#{name}")).nil?
- if is_container? type
- oprot.write_field_begin(name, type, fid)
- write_container(oprot, value, struct_fields[fid])
- oprot.write_field_end
- else
- oprot.write_field(name, type, fid, value)
- end
+ 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}"))
+ if is_container? type
+ oprot.write_field_begin(name, type, fid)
+ write_container(oprot, value, field_info)
+ oprot.write_field_end
+ else
+ oprot.write_field(name, type, fid, value)
end
end
- oprot.write_field_stop
- oprot.write_struct_end
- # end
+ end
+ oprot.write_field_stop
+ oprot.write_struct_end
end
def ==(other)
- return false unless other.is_a?(self.class)
- each_field do |fid, type, name, default|
+ each_field do |fid, field_info|
+ name = field_info[:name]
return false unless self.instance_variable_get("@#{name}") == other.instance_variable_get("@#{name}")
end
true
end
def eql?(other)
self.class == other.class && self == other
end
- # for the time being, we're ok with a naive hash. this could definitely be improved upon.
def hash
- 0
+ field_values = []
+ each_field do |fid, field_info|
+ name = field_info[:name]
+ field_values << self.instance_variable_get("@#{name}")
+ end
+ field_values.hash
end
+ def differences(other)
+ diffs = []
+ unless other.is_a?(self.class)
+ diffs << "Different class!"
+ else
+ each_field do |fid, field_info|
+ name = field_info[:name]
+ diffs << "#{name} differs!" unless self.instance_variable_get("@#{name}") == other.instance_variable_get("@#{name}")
+ 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
@@ -254,19 +277,22 @@
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)
- [Types::LIST, Types::MAP, Types::SET].include? 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
- deprecate_module! :ThriftStruct => Struct
end