grpc-rest 0.1.17 → 0.1.18

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: c9364ed8060e0d6d89f6082f0da592a34adb7977c36b776be56ee8e816bf9575
4
- data.tar.gz: 8358915b2c4cea7d0950fb9198395b11d70a94e8800e3e52f9781bfcf18707be
3
+ metadata.gz: 8c776db1bb156562864c41be6a4af47debe30d420329359847e71db6b5913711
4
+ data.tar.gz: 7c4745a5d2dd7e560d0e18b022972473a4487bedf9b9efc4ba387d5cbe42bfc0
5
5
  SHA512:
6
- metadata.gz: cfaea51fd7addb1aedc0c3f4c7ea8450af57716c146d46342331d52c4d6df56df835609477692c3c8ec0985f5164f82be7b0261f60a7241b2723b6aa9c62f8ba
7
- data.tar.gz: 665cf40abf886db39d3c34d253b1eeb457a3b204d8c254a0737cdb41b8e754a7c1d2f2159bccdf89a8d1efdad075d10b67982bac23d2cbf5c1238510449c1280
6
+ metadata.gz: 4e7f53b6c264c80f768dd91c0c25da350651cd386d7a51b88f7eedf814d2f0eced41a261ee9e3800ba867fdb69bc4a87ac22700c6b33ae3d50d576555b66875e
7
+ data.tar.gz: 456d38962848fc73f1c40f0a59336de1d17017e2e138511f046836674a947a11390b20b7180a4b7d4d5befa6f132a23793d5cc7518263a93c1ed0be8255fa246
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.18 - 2024-08-15
11
+ - Automatically add prefixes to enum values if not provided
12
+
10
13
  # 0.1.17 - 2024-07-30
11
14
  - Ignore unknown fields in JSON decoding
12
15
 
@@ -1,3 +1,3 @@
1
1
  module GrpcRest
2
- VERSION = '0.1.17'
2
+ VERSION = '0.1.18'
3
3
  end
data/lib/grpc_rest.rb CHANGED
@@ -37,12 +37,45 @@ module GrpcRest
37
37
  proto.public_send(:"#{tokens.last}=", value) if proto.respond_to?(:"#{tokens.last}=")
38
38
  end
39
39
 
40
+ # https://stackoverflow.com/a/2158473/5199431
41
+ def longest_common_substring(arr)
42
+ return "" if arr.empty?
43
+
44
+ result = 0
45
+ first_val = arr[0]
46
+ (0...first_val.length).each do |k|
47
+ all_matched = true
48
+ character = first_val[k]
49
+ arr.each { |str| all_matched &= (character == str[k]) }
50
+ break unless all_matched
51
+ result += 1
52
+ end
53
+ first_val.slice(0, result)
54
+ end
55
+
56
+ def handle_enum_values(descriptor, value)
57
+ names = descriptor.subtype.to_h.keys.map(&:to_s)
58
+ prefix = longest_common_substring(names)
59
+ if prefix.present? && !value.starts_with?(prefix)
60
+ "#{prefix}#{value}"
61
+ else
62
+ value
63
+ end
64
+ end
65
+
40
66
  def map_proto_type(proto, params)
41
67
  proto.to_a.each do |descriptor|
42
68
  field = descriptor.name
43
69
  val = params[field]
44
70
  next if val.nil?
45
- next if descriptor.subtype.is_a?(Google::Protobuf::EnumDescriptor)
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
46
79
 
47
80
  case descriptor.type
48
81
  when *%i(int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64)
@@ -18,6 +18,7 @@ message TestRequest {
18
18
  google.protobuf.Value bare_value = 9;
19
19
  repeated SubRecord sub_records = 10;
20
20
  int32 some_int = 11;
21
+ TestEnum some_enum = 12;
21
22
  }
22
23
 
23
24
  message SubRecord {
@@ -30,6 +31,12 @@ message TestResponse {
30
31
  string full_response = 2;
31
32
  }
32
33
 
34
+ enum TestEnum {
35
+ TEST_ENUM_UNSPECIFIED = 0;
36
+ TEST_ENUM_FOO = 1;
37
+ TEST_ENUM_BAR = 2;
38
+ }
39
+
33
40
  service MyService {
34
41
  rpc Test(TestRequest) returns (TestResponse) {
35
42
  option (google.api.http) = {
@@ -63,8 +63,8 @@ RSpec.describe MyServiceController, type: :request do
63
63
  end
64
64
 
65
65
  describe 'full body splat' do
66
- it 'should be successful' do
67
- params = {
66
+ let(:params) do
67
+ {
68
68
  test_id: 'abc',
69
69
  some_int: "65",
70
70
  foobar: 'xyz',
@@ -91,12 +91,26 @@ RSpec.describe MyServiceController, type: :request do
91
91
  list_value: ['F', 'Y', 'I'],
92
92
  bare_value: 45,
93
93
  timestamp_field: '2024-04-03 01:02:03 UTC',
94
+ some_enum: 'TEST_ENUM_FOO'
94
95
  }
96
+ end
97
+
98
+ it 'should be successful' do
99
+ post '/test4', params: params, as: :json
100
+ expect(response).to be_successful
101
+ expect(response.parsed_body).to eq({
102
+ 'someInt' => 4,
103
+ '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"})
104
+ })
105
+ end
106
+
107
+ it 'should be successful without the enum prefix' do
108
+ params[:some_enum] = 'FOO'
95
109
  post '/test4', params: params, as: :json
96
110
  expect(response).to be_successful
97
111
  expect(response.parsed_body).to eq({
98
112
  'someInt' => 4,
99
- '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})
113
+ '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"})
100
114
  })
101
115
  end
102
116
  end
@@ -9,7 +9,7 @@ require 'google/protobuf/struct_pb'
9
9
  require 'google/protobuf/timestamp_pb'
10
10
 
11
11
 
12
- descriptor_data = "\n\x12test_service.proto\x12\x08testdata\x1a\x1cgoogle/api/annotations.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x98\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\"/\n\tSubRecord\x12\x0e\n\x06sub_id\x18\x01 \x01(\t\x12\x12\n\nanother_id\x18\x02 \x01(\t\"7\n\x0cTestResponse\x12\x10\n\x08some_int\x18\x01 \x01(\x05\x12\x15\n\rfull_response\x18\x02 \x01(\t2\xdf\x02\n\tMyService\x12T\n\x04Test\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x1d\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"
12
+ descriptor_data = "\n\x12test_service.proto\x12\x08testdata\x1a\x1cgoogle/api/annotations.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.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\"7\n\x0cTestResponse\x12\x10\n\x08some_int\x18\x01 \x01(\x05\x12\x15\n\rfull_response\x18\x02 \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\xdf\x02\n\tMyService\x12T\n\x04Test\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x1d\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
13
 
14
14
  pool = Google::Protobuf::DescriptorPool.generated_pool
15
15
  pool.add_serialized_file(descriptor_data)
@@ -18,4 +18,5 @@ module Testdata
18
18
  TestRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("testdata.TestRequest").msgclass
19
19
  SubRecord = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("testdata.SubRecord").msgclass
20
20
  TestResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("testdata.TestResponse").msgclass
21
+ TestEnum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("testdata.TestEnum").enummodule
21
22
  end
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.17
4
+ version: 0.1.18
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-07-30 00:00:00.000000000 Z
11
+ date: 2024-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: grpc