Search code examples
rubythrift

How to get thrift type of an attribute?


I would like to process many attributes automatically. But my data are read from a file and they are string type... I would like to know if there is a solution to know the type of attribute. Thanks to this, I'll be able to convert string into the right type.

struct Test{
1: i32 id,
2: string name,
3: Enumeration genre
}

test = Test.new

A method which does (for example) :

puts test.id.type  => Give me i32
puts test.name.type  => Give me string

Etc..

I can use test.id.class but it doesn't work .. (it tells me nilClass when it isn't assigned)

And even if "id" is a i32,

test.id = "blabla"  => works... (normally, it shouldn't)

The verification of type is done only when you try to serialize... not when you assign a value into a thrift object.

Thank you !


Solution

  • This might help: Thrift.type_checking=true, will cause exception to be raised if type does not match

    >> Thrift.type_checking
    => false
    >> Thrift.type_checking=true
    => true
    >> test=Test.new
    => Test id:nil, name:nil
    >> test.id="Hi"
    Thrift::TypeError: Expected Types::I32, received String for field id
        from /usr/lib/ruby/gems/1.8/gems/thrift-0.9.1.1/lib/thrift/types.rb:69:in `check_type'
        from /usr/lib/ruby/gems/1.8/gems/thrift-0.9.1.1/lib/thrift/struct.rb:157:in `id='
        from (irb):4
    

    Orig answer

    Not sure exactly what you are looking for but seems to look for thrift-specific reflection

    You can get the list of member types of a struct, if that helps

    test.struct_fields.each{|fid,v| puts "#{fid}: #{v[:name]} #{v[:type]}"}

    And you can also get the field ID as key into struct_fields if you took the struct class and referenced the field name (all caps), so could you do something with this?

    test.struct_fields[Test::ID][:type]
    

    Value can be matched against constants in Thrift::Types such as I16

    You can also use the validate method on the struct, after you assigned (so you can avoid failing the serialization)
    Edit: I misspoke - the validate method does not validate values, just that required fields exist. I guess there is no such thing, as the current validation happens in the specific protocols. You could just attempt serialization if you wanted or just write a generic validator that for a given field it uses the type (as seen above) to test

    That having been said - I checked out the library code thinking that the generated accessors could be modified to do it, And it looks like they may have that capability already, see https://github.com/apache/thrift/blob/master/lib/rb/lib/thrift/struct.rb#L157