grpc-rest 0.1.19 → 0.1.20

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 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