protobuf-cucumber 3.10.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rubocop.yml +70 -0
- data/.rubocop_todo.yml +145 -0
- data/.travis.yml +40 -0
- data/.yardopts +5 -0
- data/CHANGES.md +344 -0
- data/CONTRIBUTING.md +16 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +64 -0
- data/bin/protoc-gen-ruby +22 -0
- data/bin/rpc_server +5 -0
- data/install-protobuf.sh +28 -0
- data/lib/protobuf.rb +129 -0
- data/lib/protobuf/cli.rb +257 -0
- data/lib/protobuf/code_generator.rb +120 -0
- data/lib/protobuf/decoder.rb +28 -0
- data/lib/protobuf/deprecation.rb +117 -0
- data/lib/protobuf/descriptors.rb +3 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +62 -0
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +301 -0
- data/lib/protobuf/encoder.rb +11 -0
- data/lib/protobuf/enum.rb +365 -0
- data/lib/protobuf/exceptions.rb +9 -0
- data/lib/protobuf/field.rb +74 -0
- data/lib/protobuf/field/base_field.rb +380 -0
- data/lib/protobuf/field/base_field_object_definitions.rb +504 -0
- data/lib/protobuf/field/bool_field.rb +64 -0
- data/lib/protobuf/field/bytes_field.rb +78 -0
- data/lib/protobuf/field/double_field.rb +25 -0
- data/lib/protobuf/field/enum_field.rb +61 -0
- data/lib/protobuf/field/field_array.rb +104 -0
- data/lib/protobuf/field/field_hash.rb +122 -0
- data/lib/protobuf/field/fixed32_field.rb +25 -0
- data/lib/protobuf/field/fixed64_field.rb +28 -0
- data/lib/protobuf/field/float_field.rb +43 -0
- data/lib/protobuf/field/int32_field.rb +21 -0
- data/lib/protobuf/field/int64_field.rb +34 -0
- data/lib/protobuf/field/integer_field.rb +23 -0
- data/lib/protobuf/field/message_field.rb +51 -0
- data/lib/protobuf/field/sfixed32_field.rb +27 -0
- data/lib/protobuf/field/sfixed64_field.rb +28 -0
- data/lib/protobuf/field/signed_integer_field.rb +29 -0
- data/lib/protobuf/field/sint32_field.rb +21 -0
- data/lib/protobuf/field/sint64_field.rb +21 -0
- data/lib/protobuf/field/string_field.rb +51 -0
- data/lib/protobuf/field/uint32_field.rb +21 -0
- data/lib/protobuf/field/uint64_field.rb +21 -0
- data/lib/protobuf/field/varint_field.rb +77 -0
- data/lib/protobuf/generators/base.rb +85 -0
- data/lib/protobuf/generators/enum_generator.rb +39 -0
- data/lib/protobuf/generators/extension_generator.rb +27 -0
- data/lib/protobuf/generators/field_generator.rb +193 -0
- data/lib/protobuf/generators/file_generator.rb +262 -0
- data/lib/protobuf/generators/group_generator.rb +122 -0
- data/lib/protobuf/generators/message_generator.rb +104 -0
- data/lib/protobuf/generators/option_generator.rb +17 -0
- data/lib/protobuf/generators/printable.rb +160 -0
- data/lib/protobuf/generators/service_generator.rb +50 -0
- data/lib/protobuf/lifecycle.rb +33 -0
- data/lib/protobuf/logging.rb +39 -0
- data/lib/protobuf/message.rb +260 -0
- data/lib/protobuf/message/fields.rb +233 -0
- data/lib/protobuf/message/serialization.rb +85 -0
- data/lib/protobuf/optionable.rb +70 -0
- data/lib/protobuf/rpc/buffer.rb +78 -0
- data/lib/protobuf/rpc/client.rb +140 -0
- data/lib/protobuf/rpc/connectors/base.rb +221 -0
- data/lib/protobuf/rpc/connectors/ping.rb +89 -0
- data/lib/protobuf/rpc/connectors/socket.rb +78 -0
- data/lib/protobuf/rpc/connectors/zmq.rb +319 -0
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +50 -0
- data/lib/protobuf/rpc/env.rb +60 -0
- data/lib/protobuf/rpc/error.rb +28 -0
- data/lib/protobuf/rpc/error/client_error.rb +31 -0
- data/lib/protobuf/rpc/error/server_error.rb +43 -0
- data/lib/protobuf/rpc/middleware.rb +25 -0
- data/lib/protobuf/rpc/middleware/exception_handler.rb +40 -0
- data/lib/protobuf/rpc/middleware/logger.rb +95 -0
- data/lib/protobuf/rpc/middleware/request_decoder.rb +79 -0
- data/lib/protobuf/rpc/middleware/response_encoder.rb +83 -0
- data/lib/protobuf/rpc/middleware/runner.rb +18 -0
- data/lib/protobuf/rpc/rpc.pb.rb +64 -0
- data/lib/protobuf/rpc/rpc_method.rb +16 -0
- data/lib/protobuf/rpc/server.rb +39 -0
- data/lib/protobuf/rpc/servers/socket/server.rb +121 -0
- data/lib/protobuf/rpc/servers/socket/worker.rb +56 -0
- data/lib/protobuf/rpc/servers/socket_runner.rb +46 -0
- data/lib/protobuf/rpc/servers/zmq/broker.rb +194 -0
- data/lib/protobuf/rpc/servers/zmq/server.rb +321 -0
- data/lib/protobuf/rpc/servers/zmq/util.rb +48 -0
- data/lib/protobuf/rpc/servers/zmq/worker.rb +105 -0
- data/lib/protobuf/rpc/servers/zmq_runner.rb +70 -0
- data/lib/protobuf/rpc/service.rb +172 -0
- data/lib/protobuf/rpc/service_directory.rb +261 -0
- data/lib/protobuf/rpc/service_dispatcher.rb +45 -0
- data/lib/protobuf/rpc/service_filters.rb +250 -0
- data/lib/protobuf/rpc/stat.rb +119 -0
- data/lib/protobuf/socket.rb +21 -0
- data/lib/protobuf/tasks.rb +1 -0
- data/lib/protobuf/tasks/compile.rake +80 -0
- data/lib/protobuf/varint.rb +20 -0
- data/lib/protobuf/varint_pure.rb +31 -0
- data/lib/protobuf/version.rb +3 -0
- data/lib/protobuf/wire_type.rb +10 -0
- data/lib/protobuf/zmq.rb +21 -0
- data/profile.html +5103 -0
- data/proto/dynamic_discovery.proto +44 -0
- data/proto/google/protobuf/compiler/plugin.proto +147 -0
- data/proto/google/protobuf/descriptor.proto +779 -0
- data/proto/rpc.proto +69 -0
- data/protobuf-cucumber.gemspec +57 -0
- data/spec/benchmark/tasks.rb +143 -0
- data/spec/bin/protoc-gen-ruby_spec.rb +23 -0
- data/spec/encoding/all_types_spec.rb +103 -0
- data/spec/encoding/extreme_values_spec.rb +0 -0
- data/spec/functional/class_inheritance_spec.rb +52 -0
- data/spec/functional/code_generator_spec.rb +58 -0
- data/spec/functional/socket_server_spec.rb +59 -0
- data/spec/functional/zmq_server_spec.rb +105 -0
- data/spec/lib/protobuf/cli_spec.rb +317 -0
- data/spec/lib/protobuf/code_generator_spec.rb +87 -0
- data/spec/lib/protobuf/enum_spec.rb +307 -0
- data/spec/lib/protobuf/field/bool_field_spec.rb +91 -0
- data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/enum_field_spec.rb +44 -0
- data/spec/lib/protobuf/field/field_array_spec.rb +105 -0
- data/spec/lib/protobuf/field/field_hash_spec.rb +168 -0
- data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/float_field_spec.rb +90 -0
- data/spec/lib/protobuf/field/int32_field_spec.rb +120 -0
- data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/message_field_spec.rb +132 -0
- data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/string_field_spec.rb +79 -0
- data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field_spec.rb +192 -0
- data/spec/lib/protobuf/generators/base_spec.rb +154 -0
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +82 -0
- data/spec/lib/protobuf/generators/extension_generator_spec.rb +42 -0
- data/spec/lib/protobuf/generators/field_generator_spec.rb +197 -0
- data/spec/lib/protobuf/generators/file_generator_spec.rb +119 -0
- data/spec/lib/protobuf/generators/message_generator_spec.rb +0 -0
- data/spec/lib/protobuf/generators/service_generator_spec.rb +99 -0
- data/spec/lib/protobuf/lifecycle_spec.rb +94 -0
- data/spec/lib/protobuf/message_spec.rb +944 -0
- data/spec/lib/protobuf/optionable_spec.rb +265 -0
- data/spec/lib/protobuf/rpc/client_spec.rb +66 -0
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +226 -0
- data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +34 -0
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +110 -0
- data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +62 -0
- data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +49 -0
- data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +115 -0
- data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +91 -0
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +38 -0
- data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +43 -0
- data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +55 -0
- data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +35 -0
- data/spec/lib/protobuf/rpc/service_directory_spec.rb +293 -0
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +35 -0
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +517 -0
- data/spec/lib/protobuf/rpc/service_spec.rb +162 -0
- data/spec/lib/protobuf/rpc/stat_spec.rb +101 -0
- data/spec/lib/protobuf/varint_spec.rb +29 -0
- data/spec/lib/protobuf_spec.rb +105 -0
- data/spec/spec_helper.rb +42 -0
- data/spec/support/all.rb +6 -0
- data/spec/support/packed_field.rb +23 -0
- data/spec/support/protos/all_types.data.bin +0 -0
- data/spec/support/protos/all_types.data.txt +119 -0
- data/spec/support/protos/enum.pb.rb +63 -0
- data/spec/support/protos/enum.proto +37 -0
- data/spec/support/protos/extreme_values.data.bin +0 -0
- data/spec/support/protos/google_unittest.bin +0 -0
- data/spec/support/protos/google_unittest.pb.rb +798 -0
- data/spec/support/protos/google_unittest.proto +884 -0
- data/spec/support/protos/google_unittest_custom_options.bin +0 -0
- data/spec/support/protos/google_unittest_custom_options.pb.rb +361 -0
- data/spec/support/protos/google_unittest_custom_options.proto +424 -0
- data/spec/support/protos/google_unittest_import.pb.rb +55 -0
- data/spec/support/protos/google_unittest_import.proto +73 -0
- data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
- data/spec/support/protos/google_unittest_import_public.proto +41 -0
- data/spec/support/protos/map-test.bin +157 -0
- data/spec/support/protos/map-test.pb.rb +85 -0
- data/spec/support/protos/map-test.proto +68 -0
- data/spec/support/protos/multi_field_extensions.pb.rb +59 -0
- data/spec/support/protos/multi_field_extensions.proto +35 -0
- data/spec/support/protos/resource.pb.rb +172 -0
- data/spec/support/protos/resource.proto +137 -0
- data/spec/support/resource_service.rb +23 -0
- data/spec/support/server.rb +65 -0
- data/spec/support/test_app_file.rb +2 -0
- data/varint_prof.rb +82 -0
- metadata +579 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'protobuf/field/varint_field'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Field
|
5
|
+
class BoolField < VarintField
|
6
|
+
ONE = 1
|
7
|
+
FALSE_ENCODE = [0].pack('C')
|
8
|
+
FALSE_STRING = "false".freeze
|
9
|
+
FALSE_VALUES = [false, FALSE_STRING].freeze
|
10
|
+
TRUE_ENCODE = [1].pack('C')
|
11
|
+
TRUE_STRING = "true".freeze
|
12
|
+
TRUE_VALUES = [true, TRUE_STRING].freeze
|
13
|
+
ACCEPTABLES = [true, false, TRUE_STRING, FALSE_STRING].freeze
|
14
|
+
|
15
|
+
##
|
16
|
+
# Class Methods
|
17
|
+
#
|
18
|
+
|
19
|
+
def self.default
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Public Instance Methods
|
25
|
+
# #
|
26
|
+
|
27
|
+
def acceptable?(val)
|
28
|
+
ACCEPTABLES.include?(val)
|
29
|
+
end
|
30
|
+
|
31
|
+
def coerce!(val)
|
32
|
+
if TRUE_VALUES.include?(val)
|
33
|
+
true
|
34
|
+
elsif FALSE_VALUES.include?(val)
|
35
|
+
false
|
36
|
+
else
|
37
|
+
fail TypeError, "Expected value of type '#{type_class}' for field #{name}, but got '#{val.class}'"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def decode(value)
|
42
|
+
value == ONE
|
43
|
+
end
|
44
|
+
|
45
|
+
def encode(value)
|
46
|
+
value ? TRUE_ENCODE : FALSE_ENCODE
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
##
|
52
|
+
# Private Instance Methods
|
53
|
+
#
|
54
|
+
|
55
|
+
def define_accessor(simple_field_name, _fully_qualified_field_name)
|
56
|
+
super
|
57
|
+
message_class.class_eval do
|
58
|
+
alias_method "#{simple_field_name}?", simple_field_name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'protobuf/wire_type'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Field
|
5
|
+
class BytesField < BaseField
|
6
|
+
|
7
|
+
##
|
8
|
+
# Constants
|
9
|
+
#
|
10
|
+
|
11
|
+
BYTES_ENCODING = Encoding::BINARY
|
12
|
+
|
13
|
+
##
|
14
|
+
# Class Methods
|
15
|
+
#
|
16
|
+
|
17
|
+
def self.default
|
18
|
+
''
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Public Instance Methods
|
23
|
+
#
|
24
|
+
|
25
|
+
def acceptable?(val)
|
26
|
+
val.is_a?(String) || val.nil? || val.is_a?(Symbol) || val.is_a?(::Protobuf::Message)
|
27
|
+
end
|
28
|
+
|
29
|
+
def decode(bytes)
|
30
|
+
bytes.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
|
31
|
+
bytes
|
32
|
+
end
|
33
|
+
|
34
|
+
def encode(value)
|
35
|
+
value_to_encode = if value.is_a?(::Protobuf::Message)
|
36
|
+
value.encode
|
37
|
+
else
|
38
|
+
"" + value
|
39
|
+
end
|
40
|
+
|
41
|
+
value_to_encode.force_encoding(::Protobuf::Field::BytesField::BYTES_ENCODING)
|
42
|
+
"#{::Protobuf::Field::VarintField.encode(value_to_encode.bytesize)}#{value_to_encode}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def wire_type
|
46
|
+
::Protobuf::WireType::LENGTH_DELIMITED
|
47
|
+
end
|
48
|
+
|
49
|
+
def coerce!(value)
|
50
|
+
case value
|
51
|
+
when String
|
52
|
+
if value.encoding == Encoding::ASCII_8BIT
|
53
|
+
# This is a "binary" string
|
54
|
+
value
|
55
|
+
else
|
56
|
+
# Assume the value is Base64 encoded (from JSON)
|
57
|
+
# Ideally we'd do the Base64 decoding while processing the JSON,
|
58
|
+
# but this is tricky to do since we don't know the protobuf field
|
59
|
+
# types when we do that.
|
60
|
+
Base64.decode64(value)
|
61
|
+
end
|
62
|
+
when Symbol
|
63
|
+
value.to_s
|
64
|
+
when NilClass
|
65
|
+
nil
|
66
|
+
when ::Protobuf::Message
|
67
|
+
value.dup
|
68
|
+
else
|
69
|
+
fail TypeError, "Unacceptable value #{value} for field #{name} of type #{type_class}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def json_encode(value)
|
74
|
+
Base64.strict_encode64(value)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'protobuf/field/float_field'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Field
|
5
|
+
class DoubleField < FloatField
|
6
|
+
|
7
|
+
##
|
8
|
+
# Public Instance Methods
|
9
|
+
#
|
10
|
+
|
11
|
+
def decode(bytes)
|
12
|
+
bytes.unpack('E').first
|
13
|
+
end
|
14
|
+
|
15
|
+
def encode(value)
|
16
|
+
[value].pack('E')
|
17
|
+
end
|
18
|
+
|
19
|
+
def wire_type
|
20
|
+
WireType::FIXED64
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'protobuf/field/integer_field'
|
2
|
+
|
3
|
+
module Protobuf
|
4
|
+
module Field
|
5
|
+
class EnumField < IntegerField
|
6
|
+
|
7
|
+
##
|
8
|
+
# Class Methods
|
9
|
+
#
|
10
|
+
|
11
|
+
def self.default
|
12
|
+
fail NoMethodError, "#{self}.#{__method__} must be called on an instance"
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Public Instance Methods
|
17
|
+
#
|
18
|
+
def encode(value)
|
19
|
+
# original Google's library uses 64bits integer for negative value
|
20
|
+
::Protobuf::Field::VarintField.encode(value.to_i & 0xffff_ffff_ffff_ffff)
|
21
|
+
end
|
22
|
+
|
23
|
+
def decode(value)
|
24
|
+
value -= 0x1_0000_0000_0000_0000 if (value & 0x8000_0000_0000_0000).nonzero?
|
25
|
+
value if acceptable?(value)
|
26
|
+
end
|
27
|
+
|
28
|
+
def acceptable?(val)
|
29
|
+
!type_class.fetch(val).nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
def enum?
|
33
|
+
true
|
34
|
+
end
|
35
|
+
|
36
|
+
def coerce!(value)
|
37
|
+
type_class.fetch(value) || fail(TypeError, "Invalid Enum value: #{value.inspect} for #{name}")
|
38
|
+
end
|
39
|
+
|
40
|
+
def json_encode(value)
|
41
|
+
enum = type_class.enums.find { |e| e.to_i == value }
|
42
|
+
enum.to_s(:name)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
##
|
48
|
+
# Private Instance Methods
|
49
|
+
#
|
50
|
+
|
51
|
+
def typed_default_value
|
52
|
+
if default.is_a?(Symbol)
|
53
|
+
type_class.const_get(default)
|
54
|
+
else
|
55
|
+
type_class.fetch(default) || type_class.enums.first
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Protobuf
|
2
|
+
module Field
|
3
|
+
class FieldArray < Array
|
4
|
+
|
5
|
+
##
|
6
|
+
# Attributes
|
7
|
+
#
|
8
|
+
|
9
|
+
attr_reader :field
|
10
|
+
|
11
|
+
##
|
12
|
+
# Constructor
|
13
|
+
#
|
14
|
+
|
15
|
+
def initialize(field)
|
16
|
+
@field = field
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Public Instance Methods
|
21
|
+
#
|
22
|
+
|
23
|
+
def []=(nth, val)
|
24
|
+
super(nth, normalize(val)) unless val.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
def <<(val)
|
28
|
+
super(normalize(val)) unless val.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
def push(val)
|
32
|
+
super(normalize(val)) unless val.nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
def replace(val)
|
36
|
+
raise_type_error(val) unless val.is_a?(Array)
|
37
|
+
val.map! { |v| normalize(v) }
|
38
|
+
super(val)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Return a hash-representation of the given values for this field type.
|
42
|
+
# The value in this case would be an array.
|
43
|
+
def to_hash_value
|
44
|
+
map do |value|
|
45
|
+
value.respond_to?(:to_hash_value) ? value.to_hash_value : value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Return a hash-representation of the given values for this field type
|
50
|
+
# that is safe to convert to JSON.
|
51
|
+
# The value in this case would be an array.
|
52
|
+
def to_json_hash_value(options = {})
|
53
|
+
if field.respond_to?(:json_encode)
|
54
|
+
map do |value|
|
55
|
+
field.json_encode(value)
|
56
|
+
end
|
57
|
+
else
|
58
|
+
map do |value|
|
59
|
+
value.respond_to?(:to_json_hash_value) ? value.to_json_hash_value(options) : value
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_s
|
65
|
+
"[#{field.name}]"
|
66
|
+
end
|
67
|
+
|
68
|
+
def unshift(val)
|
69
|
+
super(normalize(val)) unless val.nil?
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
##
|
75
|
+
# Private Instance Methods
|
76
|
+
#
|
77
|
+
|
78
|
+
def normalize(value)
|
79
|
+
value = value.to_proto if value.respond_to?(:to_proto)
|
80
|
+
fail TypeError, "Unacceptable value #{value} for field #{field.name} of type #{field.type_class}" unless field.acceptable?(value)
|
81
|
+
|
82
|
+
if field.is_a?(::Protobuf::Field::EnumField)
|
83
|
+
field.type_class.fetch(value)
|
84
|
+
elsif field.is_a?(::Protobuf::Field::BytesField)
|
85
|
+
field.coerce!(value)
|
86
|
+
elsif field.is_a?(::Protobuf::Field::MessageField) && value.is_a?(field.type_class)
|
87
|
+
value
|
88
|
+
elsif field.is_a?(::Protobuf::Field::MessageField) && value.respond_to?(:to_hash)
|
89
|
+
field.type_class.new(value.to_hash)
|
90
|
+
else
|
91
|
+
value
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def raise_type_error(val)
|
96
|
+
fail TypeError, <<-TYPE_ERROR
|
97
|
+
Expected repeated value of type '#{field.type_class}'
|
98
|
+
Got '#{val.class}' for repeated protobuf field #{field.name}
|
99
|
+
TYPE_ERROR
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Protobuf
|
2
|
+
module Field
|
3
|
+
class FieldHash < Hash
|
4
|
+
|
5
|
+
##
|
6
|
+
# Attributes
|
7
|
+
#
|
8
|
+
|
9
|
+
attr_reader :field, :key_field, :value_field
|
10
|
+
|
11
|
+
##
|
12
|
+
# Constructor
|
13
|
+
#
|
14
|
+
|
15
|
+
def initialize(field)
|
16
|
+
@field = field
|
17
|
+
@key_field = field.type_class.get_field(:key)
|
18
|
+
@value_field = field.type_class.get_field(:value)
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Public Instance Methods
|
23
|
+
#
|
24
|
+
|
25
|
+
def []=(key, val)
|
26
|
+
super(normalize_key(key), normalize_val(val))
|
27
|
+
end
|
28
|
+
|
29
|
+
alias store []=
|
30
|
+
|
31
|
+
def replace(val)
|
32
|
+
raise_type_error(val) unless val.is_a?(Hash)
|
33
|
+
clear
|
34
|
+
update(val)
|
35
|
+
end
|
36
|
+
|
37
|
+
def merge!(other)
|
38
|
+
raise_type_error(other) unless other.is_a?(Hash)
|
39
|
+
# keys and values will be normalized by []= above
|
40
|
+
other.each { |k, v| self[k] = v }
|
41
|
+
end
|
42
|
+
|
43
|
+
alias update merge!
|
44
|
+
|
45
|
+
# Return a hash-representation of the given values for this field type.
|
46
|
+
# The value in this case would be the hash itself, right? Unfortunately
|
47
|
+
# not because the values of the map could be messages themselves that we
|
48
|
+
# need to transform.
|
49
|
+
def to_hash_value
|
50
|
+
each_with_object({}) do |(key, value), hash|
|
51
|
+
hash[key] = value.respond_to?(:to_hash_value) ? value.to_hash_value : value
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Return a hash-representation of the given values for this field type
|
56
|
+
# that is safe to convert to JSON.
|
57
|
+
#
|
58
|
+
# The value in this case would be the hash itself, right? Unfortunately
|
59
|
+
# not because the values of the map could be messages themselves that we
|
60
|
+
# need to transform.
|
61
|
+
def to_json_hash_value(options = {})
|
62
|
+
if field.respond_to?(:json_encode)
|
63
|
+
each_with_object({}) do |(key, value), hash|
|
64
|
+
hash[key] = field.json_encode(value)
|
65
|
+
end
|
66
|
+
else
|
67
|
+
each_with_object({}) do |(key, value), hash|
|
68
|
+
hash[key] = value.respond_to?(:to_json_hash_value) ? value.to_json_hash_value(options) : value
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_s
|
74
|
+
"{#{field.name}}"
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
##
|
80
|
+
# Private Instance Methods
|
81
|
+
#
|
82
|
+
|
83
|
+
def normalize_key(key)
|
84
|
+
normalize(:key, key, key_field)
|
85
|
+
end
|
86
|
+
|
87
|
+
def normalize_val(value)
|
88
|
+
normalize(:value, value, value_field)
|
89
|
+
end
|
90
|
+
|
91
|
+
def normalize(what, value, normalize_field)
|
92
|
+
raise_type_error(value) if value.nil?
|
93
|
+
value = value.to_proto if value.respond_to?(:to_proto)
|
94
|
+
fail TypeError, "Unacceptable #{what} #{value} for field #{field.name} of type #{normalize_field.type_class}" unless normalize_field.acceptable?(value)
|
95
|
+
|
96
|
+
if normalize_field.is_a?(::Protobuf::Field::EnumField)
|
97
|
+
fetch_enum(normalize_field.type_class, value)
|
98
|
+
elsif normalize_field.is_a?(::Protobuf::Field::MessageField) && value.is_a?(normalize_field.type_class)
|
99
|
+
value
|
100
|
+
elsif normalize_field.is_a?(::Protobuf::Field::MessageField) && value.respond_to?(:to_hash)
|
101
|
+
normalize_field.type_class.new(value.to_hash)
|
102
|
+
else
|
103
|
+
value
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def fetch_enum(type, val)
|
108
|
+
en = type.fetch(val)
|
109
|
+
raise_type_error(val) if en.nil?
|
110
|
+
en
|
111
|
+
end
|
112
|
+
|
113
|
+
def raise_type_error(val)
|
114
|
+
fail TypeError, <<-TYPE_ERROR
|
115
|
+
Expected map value of type '#{key_field.type_class} -> #{value_field.type_class}'
|
116
|
+
Got '#{val.class}' for map protobuf field #{field.name}
|
117
|
+
TYPE_ERROR
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|