sparsam 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'sparsam_native'
3
+
4
+ require 'sparsam/types'
5
+ require 'sparsam/exceptions'
6
+ require 'sparsam/struct'
7
+ require 'sparsam/union'
8
+ require 'sparsam/deserializer'
9
+
10
+ Sparsam.init!
@@ -0,0 +1,97 @@
1
+ require 'set'
2
+ require 'sparsam/types'
3
+
4
+ module Sparsam
5
+ class BaseClass
6
+ class AccessorNames < Struct.new(:reader, :writer); end
7
+
8
+ def self.generate_field_syms(klass)
9
+ field_syms = {}
10
+ klass::FIELDS.each do |_, field_info|
11
+ name = field_info[:name].to_sym
12
+ accessors = AccessorNames.new(name, :"#{name}=")
13
+ field_syms[name] = accessors
14
+ field_syms[name.to_s] = accessors
15
+ end
16
+
17
+ klass.const_set(
18
+ :FIELD_SYMS,
19
+ field_syms
20
+ )
21
+ end
22
+
23
+ def self.generate_accessors(klass)
24
+ klass::FIELDS.each do |field_key, field_info|
25
+ field_accessor(klass, field_key, field_info)
26
+ qmark_isset_method(klass, field_info)
27
+ end
28
+ end
29
+
30
+ # TODO(Ben Hughes): Do we ever use those, these are an unexpected
31
+ # definition of predicate accessors
32
+ def self.qmark_isset_method(klass, field_info)
33
+ field_name = field_info[:name]
34
+
35
+ klass.class_eval(<<-EOF, __FILE__, __LINE__)
36
+ def #{field_name}?
37
+ !#{field_name}.nil?
38
+ end
39
+ EOF
40
+ end
41
+
42
+ def self.generate_default_values(klass)
43
+ fields_with_default_values = {}
44
+ klass::FIELDS.each do |fid, field_def|
45
+ unless field_def[:default].nil?
46
+ fields_with_default_values[field_def[:name]] = field_def[:default].freeze
47
+ end
48
+ end
49
+
50
+ if fields_with_default_values.empty?
51
+ klass.const_set(
52
+ :DEFAULT_VALUES,
53
+ nil
54
+ )
55
+ else
56
+ klass.const_set(
57
+ :DEFAULT_VALUES,
58
+ fields_with_default_values
59
+ )
60
+ end
61
+ end
62
+
63
+ def self.init_thrift_struct(klass)
64
+ generate_accessors(klass)
65
+ generate_field_syms(klass)
66
+ Sparsam.cache_fields(klass)
67
+ generate_default_values(klass)
68
+ klass.class_eval(<<-EOF, __FILE__, __LINE__)
69
+ def struct_fields
70
+ FIELDS
71
+ end
72
+ EOF
73
+ end
74
+
75
+ def serialize(prot = Sparsam::CompactProtocol)
76
+ validate
77
+ s = Sparsam::Serializer.new(prot, "")
78
+ s.serialize(self.class, self)
79
+ end
80
+
81
+ def validate(mode = Sparsam::NORMAL)
82
+ Sparsam.validate(self.class, self, mode)
83
+ end
84
+
85
+ private
86
+
87
+ def name_to_accessors(name)
88
+ self.class::FIELD_SYMS[name]
89
+ end
90
+
91
+ def each_field
92
+ struct_fields.each do |fid, data|
93
+ yield fid, data
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,8 @@
1
+ module Sparsam
2
+ module Deserializer
3
+ def self.deserialize(klass, serialized_string, prot = Sparsam::CompactProtocol)
4
+ s = Sparsam::Serializer.new(prot, serialized_string)
5
+ s.deserialize(klass)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,33 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ module Sparsam
4
+ class Exception < StandardError
5
+ def initialize(msg)
6
+ super
7
+ end
8
+ end
9
+
10
+ class MissingMandatory < Exception
11
+ def initialize(msg)
12
+ super
13
+ end
14
+ end
15
+
16
+ class TypeMismatch < Exception
17
+ def initialize(msg)
18
+ super
19
+ end
20
+ end
21
+
22
+ class UnionException < Exception
23
+ def initialize(msg)
24
+ super
25
+ end
26
+ end
27
+
28
+ class UnknownTypeException < Exception
29
+ def initialize(msg)
30
+ super
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,45 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'sparsam/base_class'
3
+
4
+ module Sparsam
5
+ class Struct < ::Sparsam::BaseClass
6
+ include ::Sparsam::StructInitialization
7
+
8
+ def ==(other)
9
+ return true if other.equal?(self)
10
+ return false unless other.instance_of?(self.class)
11
+
12
+ each_field do |fid, info|
13
+ reader = name_to_accessors(info[:name]).reader
14
+ return false unless send(reader) == other.send(reader)
15
+ end
16
+ end
17
+ alias_method :eql?, :==
18
+
19
+ def self.field_accessor(klass, field_key, field_info)
20
+ field_name = field_info[:name]
21
+ klass.class_eval(<<-EOF, __FILE__, __LINE__)
22
+ attr_accessor :'#{field_name}'
23
+ EOF
24
+ end
25
+
26
+ private
27
+
28
+ def assign_defaults(defaults)
29
+ defaults.each do |name, default_value|
30
+ accessors = name_to_accessors(name)
31
+ send(accessors.writer, default_value)
32
+ end
33
+ end
34
+
35
+ def assign_from_arg(d)
36
+ d.each do |name, value|
37
+ accessors = name_to_accessors(name)
38
+ unless accessors
39
+ raise Sparsam::Exception, "Unknown key given to #{self.class}.new: #{name}"
40
+ end
41
+ send(accessors.writer, value)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,108 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'set'
3
+ require 'sparsam/exceptions'
4
+
5
+ module Sparsam
6
+ module Types
7
+ STOP = 0
8
+ VOID = 1
9
+ BOOL = 2
10
+ BYTE = 3
11
+ DOUBLE = 4
12
+ I16 = 6
13
+ I32 = 8
14
+ I64 = 10
15
+ STRING = 11
16
+ STRUCT = 12
17
+ MAP = 13
18
+ SET = 14
19
+ LIST = 15
20
+
21
+ COLLECTIONS = Set.new([
22
+ SET,
23
+ LIST,
24
+ MAP,
25
+ ]).freeze
26
+ end
27
+
28
+ # Deprecated type checking
29
+
30
+ def self.check_type(value, field, name, skip_nil = true)
31
+ return if value.nil? && skip_nil
32
+
33
+ valid =
34
+ case field[:type]
35
+ when Types::VOID
36
+ nil === value
37
+ when Types::BOOL
38
+ true === value || false === value
39
+ when Types::BYTE, Types::I16, Types::I32, Types::I64
40
+ Integer === value
41
+ when Types::DOUBLE
42
+ Float === value
43
+ when Types::STRING
44
+ String === value
45
+ when Types::STRUCT
46
+ Struct === value || Union === value
47
+ when Types::MAP
48
+ Hash === value
49
+ when Types::SET
50
+ Set === value
51
+ when Types::LIST
52
+ Array === value
53
+ else
54
+ false
55
+ end
56
+
57
+ unless valid
58
+ raise TypeMismatch, "Expected #{type_name(field[:type])}, " \
59
+ "received #{value.class} for field #{name}"
60
+ end
61
+
62
+ # check elements now
63
+ case field[:type]
64
+ when Types::MAP
65
+ # This is still allocations per MAP, but better than per map entry
66
+ key_str = "#{name}.key"
67
+ value_str = "#{name}.value"
68
+
69
+ value.each_pair do |k, v|
70
+ check_type(k, field[:key], key_str, false)
71
+ check_type(v, field[:value], value_str, false)
72
+ end
73
+ when Types::SET, Types::LIST
74
+ element_str = "#{name}.element"
75
+
76
+ value.each do |el|
77
+ check_type(el, field[:element], element_str, false)
78
+ end
79
+ when Types::STRUCT
80
+ unless field[:class] == value.class
81
+ raise TypeMismatch, "Expected #{field[:class]}, received #{value.class} for field #{name}"
82
+ end
83
+ end
84
+ end
85
+
86
+ TYPE_NAME_SYM_MAPPING = Types.constants.each_with_object({}) do |const, h|
87
+ h[Types.const_get(const)] = const.to_sym
88
+ end
89
+
90
+ TYPE_NAME_MAPPING = TYPE_NAME_SYM_MAPPING.each_with_object({}) do |(k, const), h|
91
+ h[k] = "Types::#{const}".freeze
92
+ end.freeze
93
+
94
+ def self.type_name_sym(type)
95
+ TYPE_NAME_SYM_MAPPING[type]
96
+ end
97
+
98
+ def self.type_name(type)
99
+ TYPE_NAME_MAPPING[type]
100
+ end
101
+
102
+ module MessageTypes
103
+ CALL = 1
104
+ REPLY = 2
105
+ EXCEPTION = 3
106
+ ONEWAY = 4
107
+ end
108
+ end
@@ -0,0 +1,72 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'sparsam/base_class'
3
+
4
+ module Sparsam
5
+ class Union < ::Sparsam::BaseClass
6
+ def initialize(name = nil, value = nil)
7
+ if name
8
+ if name.is_a? Hash
9
+ if name.size > 1
10
+ raise ::Sparsam::UnionException,
11
+ "#{self.class} cannot be instantiated with more than one field!"
12
+ end
13
+ value = name.values.first
14
+ name = name.keys.first
15
+ end
16
+ end
17
+
18
+ if name
19
+ accessors = name_to_accessors(name)
20
+ unless accessors
21
+ raise Sparsam::Exception, "Unknown key given to #{self.class}.new: #{name}"
22
+ end
23
+
24
+ send(accessors.writer, value)
25
+ end
26
+ end
27
+
28
+ def ==(other)
29
+ other.equal?(self) ||
30
+ other.instance_of?(self.class) &&
31
+ @setfield == other.get_set_field &&
32
+ get_value == other.get_value
33
+ end
34
+ alias_method :eql?, :==
35
+
36
+ def hash
37
+ [self.class.name, @setfield, get_value].hash
38
+ end
39
+
40
+ def get_set_field
41
+ @setfield
42
+ end
43
+
44
+ def get_value
45
+ if @setfield
46
+ send(name_to_accessors(@setfield).reader)
47
+ end
48
+ end
49
+
50
+ def self.field_accessor(klass, field_key, field_info)
51
+ field_name = field_info[:name]
52
+ klass.class_eval(<<-EOF, __FILE__, __LINE__)
53
+ def #{field_name}
54
+ if :'#{field_name}' == @setfield
55
+ instance_variable_get(:'@#{field_name}')
56
+ else
57
+ raise ::Sparsam::UnionException, "#{field_name} is not union's set field"
58
+ end
59
+ end
60
+
61
+ def #{field_name}=(value)
62
+ if @setfield
63
+ remove_instance_variable(:"@\#{@setfield}")
64
+ end
65
+
66
+ @setfield = :'#{field_name}'
67
+ instance_variable_set(:'@#{field_name}', value)
68
+ end
69
+ EOF
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,9 @@
1
+ #
2
+ # Autogenerated by Thrift Compiler (0.1.0)
3
+ #
4
+ # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
+ #
6
+
7
+ require 'sparsam'
8
+ require 'user_types'
9
+
@@ -0,0 +1,106 @@
1
+ #
2
+ # Autogenerated by Thrift Compiler (0.1.0)
3
+ #
4
+ # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
+ #
6
+
7
+ require 'sparsam'
8
+
9
+ module Magic
10
+ Black = 0
11
+ White = 1
12
+ Red = 2
13
+ Blue = 3
14
+ Green = 4
15
+ VALUE_MAP = {0 => "Black", 1 => "White", 2 => "Red", 3 => "Blue", 4 => "Green"}
16
+ VALID_VALUES = Set.new([Black, White, Red, Blue, Green]).freeze
17
+ end
18
+
19
+ class US < ::Sparsam::Struct
20
+ FIELDS = {
21
+ 1 => {:type => ::Sparsam::Types::I32, :name => 'id_i32', :optional => true},
22
+ 2 => {:type => ::Sparsam::Types::STRING, :name => 'id_s', :default => %q"id_s default", :binary => true, :optional => true},
23
+ 3 => {:type => ::Sparsam::Types::SET, :name => 'string_set', :element => {:type => ::Sparsam::Types::STRING}, :optional => true},
24
+ 4 => {:type => ::Sparsam::Types::SET, :name => 'int_set', :element => {:type => ::Sparsam::Types::I32}, :optional => true}
25
+ }
26
+
27
+ init_thrift_struct(self)
28
+ end
29
+
30
+ class UN < ::Sparsam::Union
31
+ FIELDS = {
32
+ 1 => {:type => ::Sparsam::Types::I32, :name => 'id_i32', :optional => true},
33
+ 2 => {:type => ::Sparsam::Types::STRING, :name => 'id_s', :optional => true}
34
+ }
35
+
36
+ init_thrift_struct(self)
37
+ end
38
+
39
+ class SS < ::Sparsam::Struct
40
+ FIELDS = {
41
+ 1 => {:type => ::Sparsam::Types::I32, :name => 'id_i32', :optional => true},
42
+ 2 => {:type => ::Sparsam::Types::STRING, :name => 'id_s', :optional => true},
43
+ 3 => {:type => ::Sparsam::Types::STRUCT, :name => 'us_i', :class => ::US, :optional => true},
44
+ 4 => {:type => ::Sparsam::Types::SET, :name => 'us_s', :element => {:type => ::Sparsam::Types::STRUCT, :class => ::US}, :optional => true},
45
+ 5 => {:type => ::Sparsam::Types::LIST, :name => 's_l', :element => {:type => ::Sparsam::Types::STRING}, :optional => true},
46
+ 6 => {:type => ::Sparsam::Types::MAP, :name => 'mappy', :key => {:type => ::Sparsam::Types::I32}, :value => {:type => ::Sparsam::Types::STRING}, :optional => true},
47
+ 7 => {:type => ::Sparsam::Types::BYTE, :name => 'byte_field', :optional => true},
48
+ 8 => {:type => ::Sparsam::Types::STRUCT, :name => 'un_field', :class => ::UN, :optional => true},
49
+ 9 => {:type => ::Sparsam::Types::I32, :name => 'magic_field', :optional => true, :enum_class => ::Magic},
50
+ 10 => {:type => ::Sparsam::Types::MAP, :name => 'troll', :key => {:type => ::Sparsam::Types::I32}, :value => {:type => ::Sparsam::Types::MAP, :key => {:type => ::Sparsam::Types::I32}, :value => {:type => ::Sparsam::Types::I32}}, :optional => true}
51
+ }
52
+
53
+ init_thrift_struct(self)
54
+ end
55
+
56
+ class MiniRequired < ::Sparsam::Struct
57
+ FIELDS = {
58
+ 1 => {:type => ::Sparsam::Types::I32, :name => 'id_i32'}
59
+ }
60
+
61
+ init_thrift_struct(self)
62
+ end
63
+
64
+ class EasilyInvalid < ::Sparsam::Struct
65
+ FIELDS = {
66
+ 1 => {:type => ::Sparsam::Types::STRUCT, :name => 'tail', :class => ::EasilyInvalid, :optional => true},
67
+ 2 => {:type => ::Sparsam::Types::SET, :name => 's_self', :element => {:type => ::Sparsam::Types::STRUCT, :class => ::EasilyInvalid}, :optional => true},
68
+ 3 => {:type => ::Sparsam::Types::LIST, :name => 'l_self', :element => {:type => ::Sparsam::Types::STRUCT, :class => ::EasilyInvalid}, :optional => true},
69
+ 4 => {:type => ::Sparsam::Types::MAP, :name => 'mappy1', :key => {:type => ::Sparsam::Types::STRUCT, :class => ::EasilyInvalid}, :value => {:type => ::Sparsam::Types::I32}, :optional => true},
70
+ 5 => {:type => ::Sparsam::Types::MAP, :name => 'mappy2', :key => {:type => ::Sparsam::Types::I32}, :value => {:type => ::Sparsam::Types::STRUCT, :class => ::EasilyInvalid}, :optional => true},
71
+ 6 => {:type => ::Sparsam::Types::MAP, :name => 'mappy3', :key => {:type => ::Sparsam::Types::STRUCT, :class => ::EasilyInvalid}, :value => {:type => ::Sparsam::Types::STRUCT, :class => ::EasilyInvalid}, :optional => true},
72
+ 7 => {:type => ::Sparsam::Types::LIST, :name => 'sure', :element => {:type => ::Sparsam::Types::MAP, :key => {:type => ::Sparsam::Types::SET, :element => {:type => ::Sparsam::Types::I32}}, :value => {:type => ::Sparsam::Types::MAP, :key => {:type => ::Sparsam::Types::I32}, :value => {:type => ::Sparsam::Types::SET, :element => {:type => ::Sparsam::Types::LIST, :element => {:type => ::Sparsam::Types::MAP, :key => {:type => ::Sparsam::Types::STRUCT, :class => ::EasilyInvalid}, :value => {:type => ::Sparsam::Types::STRING}}}}}}, :optional => true},
73
+ 8 => {:type => ::Sparsam::Types::STRUCT, :name => 'required_stuff', :class => ::MiniRequired, :optional => true},
74
+ 9 => {:type => ::Sparsam::Types::I32, :name => 'id_i32', :optional => true}
75
+ }
76
+
77
+ init_thrift_struct(self)
78
+ end
79
+
80
+ class NotSS < ::Sparsam::Struct
81
+ FIELDS = {
82
+ 1 => {:type => ::Sparsam::Types::STRING, :name => 'id_s', :optional => true},
83
+ 3 => {:type => ::Sparsam::Types::I32, :name => 'id_i32', :optional => true}
84
+ }
85
+
86
+ init_thrift_struct(self)
87
+ end
88
+
89
+ class NotSS_plus < ::Sparsam::Struct
90
+ FIELDS = {
91
+ 1 => {:type => ::Sparsam::Types::STRING, :name => 'id_s', :optional => true},
92
+ 2 => {:type => ::Sparsam::Types::STRING, :name => 'id_s2', :optional => true},
93
+ 3 => {:type => ::Sparsam::Types::I32, :name => 'id_i32', :optional => true}
94
+ }
95
+
96
+ init_thrift_struct(self)
97
+ end
98
+
99
+ class Nothing < ::Sparsam::Struct
100
+ FIELDS = {
101
+
102
+ }
103
+
104
+ init_thrift_struct(self)
105
+ end
106
+