grpc-rest 0.1.19 → 0.1.20

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c9a0fd0dc8a21c8ff8e5103a6bdffe98cc51cb522fb8dac59a65b2e9ceacc7c
4
- data.tar.gz: a42ae7274e7a9db0161e3a40374d050a334312c742d8737652ab8fd8aaa55ec4
3
+ metadata.gz: 3b19a325cd920ec6632682c8f91b54e06a09444cece910dbc176e898f8e504cb
4
+ data.tar.gz: 3fa53b62032088e7e57cae354326188cb93c22312d7dc463111b4d5a6992b68c
5
5
  SHA512:
6
- metadata.gz: 624a27f0b5345256376d3a3cbd418543339d9f604ef42866da442a4589fd0732702b61e02f37d14e31b1cb53f5d707d73a8924af45df9be65995942316b75d86
7
- data.tar.gz: d548c211f158b8095ec655691e11c1cb815382ecdfce8a42ed014fdcf82d5286e333d2894a8c5bdb3564b861beba29387b2936a39c6d28108e7d3d472da6ff45
6
+ metadata.gz: 235e5ea946e9e6b10be20485775d0f55f46b0ab1ecb7612f75e98c75be7ff0ca75b438e1649d3abc298196501615425675968cf0605f8968e3771cd8cde897e6
7
+ data.tar.gz: 10d3caaa87389dca93982af06ce8143e615d0b6b2133f9485c4d51ec6e18b043faaa836960fcc141954e0fac07b644eba50b256062a22f5fed8c5b5a4f04da4a
data/CHANGELOG CHANGED
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## UNRELEASED
9
9
 
10
+ # 0.1.20 - 2024-09-10
11
+ - Fix: Repeated float values weren't being treated as arrays and were crashing.
12
+
10
13
  # 0.1.19 - 2024-08-22
11
14
 
12
15
  - Add `emit_defaults` extension for JSON responses.
@@ -1,3 +1,3 @@
1
1
  module GrpcRest
2
- VERSION = '0.1.19'
2
+ VERSION = '0.1.20'
3
3
  end
data/lib/grpc_rest.rb CHANGED
@@ -63,56 +63,55 @@ module GrpcRest
63
63
  end
64
64
  end
65
65
 
66
- def map_proto_type(proto, params)
66
+ def map_proto_type(descriptor, val)
67
+ if descriptor.subtype.is_a?(Google::Protobuf::EnumDescriptor)
68
+ return handle_enum_values(descriptor, val)
69
+ end
70
+
71
+ case descriptor.type
72
+ when *%i(int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64)
73
+ return val.to_i
74
+ when *%i(float double)
75
+ return val.to_f
76
+ when :bool
77
+ return !!val
78
+ end
79
+
80
+ case descriptor.subtype&.name
81
+ when 'google.protobuf.Struct'
82
+ return Google::Protobuf::Struct.from_hash(val)
83
+ when 'google.protobuf.Timestamp'
84
+ if val.is_a?(Numeric)
85
+ return Google::Protobuf::Timestamp.from_time(Time.at(val))
86
+ else
87
+ return Google::Protobuf::Timestamp.from_time(Time.new(val))
88
+ end
89
+ when 'google.protobuf.Value'
90
+ return Google::Protobuf::Value.from_ruby(val)
91
+ when 'google.protobuf.ListValue'
92
+ return Google::Protobuf::ListValue.from_a(val)
93
+ else
94
+ return map_proto_record(descriptor.subtype, val)
95
+ end
96
+ end
97
+
98
+ def map_proto_record(proto, params)
67
99
  proto.to_a.each do |descriptor|
68
100
  field = descriptor.name
69
101
  val = params[field]
70
102
  next if val.nil?
71
- if descriptor.subtype.is_a?(Google::Protobuf::EnumDescriptor)
72
- if descriptor.label == :repeated
73
- params[field] = val.map { |v| handle_enum_values(descriptor, v)}
74
- else
75
- params[field] = handle_enum_values(descriptor, val)
76
- end
77
- next
78
- end
79
-
80
- case descriptor.type
81
- when *%i(int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64)
82
- params[field] = val.to_i
83
- when *%i(float double)
84
- params[field] = val.to_f
85
- when :bool
86
- params[field] = !!val
87
- end
88
103
 
89
- case descriptor.subtype&.name
90
- when 'google.protobuf.Struct'
91
- params[field] = Google::Protobuf::Struct.from_hash(val)
92
- when 'google.protobuf.Timestamp'
93
- if val.is_a?(Numeric)
94
- params[field] = Google::Protobuf::Timestamp.from_time(Time.at(val))
95
- else
96
- params[field] = Google::Protobuf::Timestamp.from_time(Time.new(val))
97
- end
98
- when 'google.protobuf.Value'
99
- params[field] = Google::Protobuf::Value.from_ruby(val)
100
- when 'google.protobuf.ListValue'
101
- params[field] = Google::Protobuf::ListValue.from_a(val)
104
+ if descriptor.label == :repeated
105
+ params[field] = val.map { |v| map_proto_type(descriptor, v) }
102
106
  else
103
- if params[field].is_a?(Array)
104
- params[field].each do |item|
105
- map_proto_type(descriptor.subtype, item)
106
- end
107
- else
108
- map_proto_type(descriptor.subtype, params[field])
109
- end
107
+ params[field] = map_proto_type(descriptor, val)
110
108
  end
111
109
  end
110
+ params
112
111
  end
113
112
 
114
113
  def init_request(request_class, params)
115
- map_proto_type(request_class.descriptor, params)
114
+ map_proto_record(request_class.descriptor, params)
116
115
  request_class.decode_json(JSON.generate(params), ignore_unknown_fields: true)
117
116
  end
118
117
 
@@ -20,6 +20,7 @@ message TestRequest {
20
20
  repeated SubRecord sub_records = 10;
21
21
  int32 some_int = 11;
22
22
  TestEnum some_enum = 12;
23
+ repeated float repeated_float = 13;
23
24
  }
24
25
 
25
26
  message SubRecord {
@@ -67,6 +67,7 @@ RSpec.describe MyServiceController, type: :request do
67
67
  let(:params) do
68
68
  {
69
69
  test_id: 'abc',
70
+ repeated_float: [1.0, 2.0],
70
71
  some_int: "65",
71
72
  foobar: 'xyz',
72
73
  repeated_string: ['W', 'T', 'F'],
@@ -101,7 +102,7 @@ RSpec.describe MyServiceController, type: :request do
101
102
  expect(response).to be_successful
102
103
  expect(response.parsed_body).to eq({
103
104
  'someInt' => 4,
104
- 'fullResponse' => %({"testId":"abc","foobar":"xyz","repeatedString":["W","T","F"],"subRecord":{"subId":"id1","anotherId":"id2"},"secondRecord":{"subId":"id3","anotherId":"id4"},"structField":{"bool_key":true,"str_key":"val","nil_key":null,"list_key":[{"inner_key":"inner_val"}],"int_key":123},"timestampField":"2024-04-03T01:02:03Z","listValue":["F","Y","I"],"bareValue":45,"someInt":65,"someEnum":"TEST_ENUM_FOO"})
105
+ 'fullResponse' => %({"testId":"abc","foobar":"xyz","repeatedString":["W","T","F"],"subRecord":{"subId":"id1","anotherId":"id2"},"secondRecord":{"subId":"id3","anotherId":"id4"},"structField":{"bool_key":true,"str_key":"val","nil_key":null,"list_key":[{"inner_key":"inner_val"}],"int_key":123},"timestampField":"2024-04-03T01:02:03Z","listValue":["F","Y","I"],"bareValue":45,"someInt":65,"someEnum":"TEST_ENUM_FOO","repeatedFloat":[1,2]})
105
106
  })
106
107
  end
107
108
 
@@ -111,7 +112,7 @@ RSpec.describe MyServiceController, type: :request do
111
112
  expect(response).to be_successful
112
113
  expect(response.parsed_body).to eq({
113
114
  'someInt' => 4,
114
- 'fullResponse' => %({"testId":"abc","foobar":"xyz","repeatedString":["W","T","F"],"subRecord":{"subId":"id1","anotherId":"id2"},"secondRecord":{"subId":"id3","anotherId":"id4"},"structField":{"bool_key":true,"str_key":"val","nil_key":null,"list_key":[{"inner_key":"inner_val"}],"int_key":123},"timestampField":"2024-04-03T01:02:03Z","listValue":["F","Y","I"],"bareValue":45,"someInt":65,"someEnum":"TEST_ENUM_FOO"})
115
+ 'fullResponse' => %({"testId":"abc","foobar":"xyz","repeatedString":["W","T","F"],"subRecord":{"subId":"id1","anotherId":"id2"},"secondRecord":{"subId":"id3","anotherId":"id4"},"structField":{"bool_key":true,"str_key":"val","nil_key":null,"list_key":[{"inner_key":"inner_val"}],"int_key":123},"timestampField":"2024-04-03T01:02:03Z","listValue":["F","Y","I"],"bareValue":45,"someInt":65,"someEnum":"TEST_ENUM_FOO","repeatedFloat":[1,2]})
115
116
  })
116
117
  end
117
118
  end
@@ -10,7 +10,7 @@ require 'google/protobuf/timestamp_pb'
10
10
  require 'protoc-gen-openapiv2/options/annotations_pb'
11
11
 
12
12
 
13
- descriptor_data = "\n\x12test_service.proto\x12\x08testdata\x1a\x1cgoogle/api/annotations.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\"\xbf\x03\n\x0bTestRequest\x12\x0f\n\x07test_id\x18\x01 \x01(\t\x12\x0e\n\x06\x66oobar\x18\x02 \x01(\t\x12\x17\n\x0frepeated_string\x18\x03 \x03(\t\x12\'\n\nsub_record\x18\x04 \x01(\x0b\x32\x13.testdata.SubRecord\x12*\n\rsecond_record\x18\x05 \x01(\x0b\x32\x13.testdata.SubRecord\x12-\n\x0cstruct_field\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x33\n\x0ftimestamp_field\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nlist_value\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.ListValue\x12*\n\nbare_value\x18\t \x01(\x0b\x32\x16.google.protobuf.Value\x12(\n\x0bsub_records\x18\n \x03(\x0b\x32\x13.testdata.SubRecord\x12\x10\n\x08some_int\x18\x0b \x01(\x05\x12%\n\tsome_enum\x18\x0c \x01(\x0e\x32\x12.testdata.TestEnum\"/\n\tSubRecord\x12\x0e\n\x06sub_id\x18\x01 \x01(\t\x12\x12\n\nanother_id\x18\x02 \x01(\t\"L\n\x0cTestResponse\x12\x10\n\x08some_int\x18\x01 \x01(\x05\x12\x15\n\rfull_response\x18\x02 \x01(\t\x12\x13\n\x0bignored_key\x18\x03 \x01(\t*K\n\x08TestEnum\x12\x19\n\x15TEST_ENUM_UNSPECIFIED\x10\x00\x12\x11\n\rTEST_ENUM_FOO\x10\x01\x12\x11\n\rTEST_ENUM_BAR\x10\x02\x32\x83\x03\n\tMyService\x12x\n\x04Test\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"A\x92\x41!j\x1f\n\x19x-grpc-rest-emit-defaults\x12\x02 \x01\x82\xd3\xe4\x93\x02\x17\x12\x15/test/{foobar=blah/*}\x12U\n\x05Test2\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x1d\x82\xd3\xe4\x93\x02\x17\"\x06/test2:\rsecond_record\x12Z\n\x05Test3\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\"\x82\xd3\xe4\x93\x02\x1c\"\x1a/test3/{sub_record.sub_id}\x12I\n\x05Test4\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x11\x82\xd3\xe4\x93\x02\x0b\"\x06/test4:\x01*b\x06proto3"
13
+ descriptor_data = "\n\x12test_service.proto\x12\x08testdata\x1a\x1cgoogle/api/annotations.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\"\xd7\x03\n\x0bTestRequest\x12\x0f\n\x07test_id\x18\x01 \x01(\t\x12\x0e\n\x06\x66oobar\x18\x02 \x01(\t\x12\x17\n\x0frepeated_string\x18\x03 \x03(\t\x12\'\n\nsub_record\x18\x04 \x01(\x0b\x32\x13.testdata.SubRecord\x12*\n\rsecond_record\x18\x05 \x01(\x0b\x32\x13.testdata.SubRecord\x12-\n\x0cstruct_field\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x33\n\x0ftimestamp_field\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nlist_value\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.ListValue\x12*\n\nbare_value\x18\t \x01(\x0b\x32\x16.google.protobuf.Value\x12(\n\x0bsub_records\x18\n \x03(\x0b\x32\x13.testdata.SubRecord\x12\x10\n\x08some_int\x18\x0b \x01(\x05\x12%\n\tsome_enum\x18\x0c \x01(\x0e\x32\x12.testdata.TestEnum\x12\x16\n\x0erepeated_float\x18\r \x03(\x02\"/\n\tSubRecord\x12\x0e\n\x06sub_id\x18\x01 \x01(\t\x12\x12\n\nanother_id\x18\x02 \x01(\t\"L\n\x0cTestResponse\x12\x10\n\x08some_int\x18\x01 \x01(\x05\x12\x15\n\rfull_response\x18\x02 \x01(\t\x12\x13\n\x0bignored_key\x18\x03 \x01(\t*K\n\x08TestEnum\x12\x19\n\x15TEST_ENUM_UNSPECIFIED\x10\x00\x12\x11\n\rTEST_ENUM_FOO\x10\x01\x12\x11\n\rTEST_ENUM_BAR\x10\x02\x32\x83\x03\n\tMyService\x12x\n\x04Test\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"A\x92\x41!j\x1f\n\x19x-grpc-rest-emit-defaults\x12\x02 \x01\x82\xd3\xe4\x93\x02\x17\x12\x15/test/{foobar=blah/*}\x12U\n\x05Test2\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x1d\x82\xd3\xe4\x93\x02\x17\"\x06/test2:\rsecond_record\x12Z\n\x05Test3\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\"\x82\xd3\xe4\x93\x02\x1c\"\x1a/test3/{sub_record.sub_id}\x12I\n\x05Test4\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x11\x82\xd3\xe4\x93\x02\x0b\"\x06/test4:\x01*b\x06proto3"
14
14
 
15
15
  pool = Google::Protobuf::DescriptorPool.generated_pool
16
16
  pool.add_serialized_file(descriptor_data)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grpc-rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.19
4
+ version: 0.1.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Orner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-22 00:00:00.000000000 Z
11
+ date: 2024-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grpc