gapic-generator 0.6.0 → 0.6.5

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/gem_templates/entrypoint.erb +1 -0
  4. data/gem_templates/gemspec.erb +0 -1
  5. data/lib/gapic/file_formatter.rb +1 -2
  6. data/lib/gapic/generator/version.rb +1 -1
  7. data/lib/gapic/{path_template.rb → path_pattern.rb} +9 -8
  8. data/lib/gapic/path_pattern/parser.rb +146 -0
  9. data/lib/gapic/path_pattern/pattern.rb +80 -0
  10. data/lib/gapic/path_pattern/segment.rb +276 -0
  11. data/lib/gapic/presenters/field_presenter.rb +12 -0
  12. data/lib/gapic/presenters/gem_presenter.rb +16 -2
  13. data/lib/gapic/presenters/method_presenter.rb +7 -3
  14. data/lib/gapic/presenters/resource_presenter.rb +23 -31
  15. data/lib/gapic/presenters/service_presenter.rb +2 -1
  16. data/lib/gapic/runner.rb +3 -1
  17. data/lib/gapic/schema/api.rb +17 -1
  18. data/lib/gapic/schema/wrappers.rb +24 -20
  19. data/lib/gapic/uri_template.rb +36 -0
  20. data/lib/gapic/uri_template/parser.rb +50 -0
  21. data/lib/google/protobuf/compiler/plugin.pb.rb +5 -1
  22. data/lib/google/protobuf/descriptor.pb.rb +1 -0
  23. data/templates/default/gem/gemfile.erb +0 -3
  24. data/templates/default/gem/readme.erb +1 -1
  25. data/templates/default/service/client/resource/_doc.erb +1 -1
  26. data/templates/default/service/client/resource/_multi.erb +4 -0
  27. data/templates/default/service/test/client.erb +1 -3
  28. data/templates/default/service/test/client_operations.erb +1 -3
  29. data/templates/default/service/test/client_paths.erb +1 -3
  30. data/templates/default/service/test/method/_bidi.erb +10 -2
  31. data/templates/default/service/test/method/_client.erb +10 -2
  32. data/templates/default/service/test/method/_normal.erb +6 -0
  33. data/templates/default/service/test/method/_server.erb +9 -1
  34. data/templates/default/service/test/method/_setup.erb +2 -2
  35. metadata +10 -21
  36. data/lib/gapic/path_template/parser.rb +0 -83
  37. data/lib/gapic/path_template/segment.rb +0 -74
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19f79c05f4e657a010e8f9663f1eefeadabd18ef4b456c137a8278bf8bb13a9e
4
- data.tar.gz: ebe4c8c756ebd1e18424eccffc986f92bcda6f694a50842ed394c7d62d91f252
3
+ metadata.gz: 27e2894595efed8561aa48e9059465257267e7f29310a806251bcc6d4d85c63f
4
+ data.tar.gz: af47f16264074317a8d02e73539208a4b43f565ae346aef480619bc73a6b1203
5
5
  SHA512:
6
- metadata.gz: 4a6689a12fcd02390d416ab8ada828f79e182e87a3230361fe32e3a8eea42d7555039b61c699903d25a5fb244c9db1857bbad1d816ea04e4de329d67c4359c74
7
- data.tar.gz: fac5801f38bb3fd92b871c2c5ab9b2d7ee7138d0947ffb0c9695bd21ea0561762fee5dc462de884b5182cbf4627c5c9148783474584b6cb4c9dc7727313f7f1c
6
+ metadata.gz: eacd1840fadb1236cb5ed7efe7ba254a977529435ee7ddff1fcee7bb900fa847ccc0a3b861098f1292a63f72e82f6065146f1f0a0260b0624dc9a184de3d3389
7
+ data.tar.gz: 8a93aaef7317b85fc048604b626af4cef13cf90ea2dd785a12180d94d71dbf0bc4ea24a34c828a04825adcfd4ae2b88e4cc3934d41de7de01b3be27f6302aaba
@@ -1,5 +1,35 @@
1
1
  # Release History for gapic-generator
2
2
 
3
+ ### 0.6.5 / 2020-07-16
4
+
5
+ * Examples in auth, rakefile, and readme should pick a non-common service.
6
+ * Emit a warning if common_services config references a nonexistent service.
7
+
8
+ ### 0.6.4 / 2020-07-13
9
+
10
+ * Fix rubocop warning on a generated multi-path helper if it could take no arguments.
11
+ * Run the rubocop file formatting step without caching.
12
+ * Fix an issue where generating a service with no options would fail.
13
+
14
+ ### 0.6.3 / 2020-06-27
15
+
16
+ * Fixes for generated tests for some cases involving proto maps.
17
+ * Fix a Ruby 2.7 keyword arguments warning in generated tests.
18
+ * Clean up bundler references in gemspecs and Gemfiles.
19
+
20
+ ### 0.6.2 / 2020-06-18
21
+
22
+ * Support for the proto3_optional
23
+ * Fixed an issue where tests for the oneof fields were not generating correctly
24
+ * Removed ruby <2.5 pin for the protobuf dependency since new protobuf supports it again
25
+ * Generated libraries now depend on gapic-common 0.3
26
+
27
+ ### 0.6.1 / 2020-06-16
28
+
29
+ * Add auto-generated disclaimer to generated tests.
30
+ * Support shortname and issue tracker URL configs.
31
+ * Refactors and minor fixes around resource template parsing.
32
+
3
33
  ### 0.6.0 / 2020-06-02
4
34
 
5
35
  * Support for clients with generic endpoint and credentials.
@@ -16,6 +16,7 @@ done
16
16
 
17
17
  mkdir -p /workspace/out/lib
18
18
  exec grpc_tools_ruby_protoc \
19
+ --experimental_allow_proto3_optional=1 \
19
20
  --proto_path=/workspace/common-protos/ --proto_path=/workspace/in/ \
20
21
  --ruby_out=/workspace/out/lib \
21
22
  --grpc_out=/workspace/out/lib \
@@ -29,7 +29,6 @@ Gem::Specification.new do |spec|
29
29
  spec.add_dependency "protobuf", "~> 3.8"
30
30
  spec.add_dependency "rubocop", "~> 0.61"
31
31
 
32
- spec.add_development_dependency "bundler", "~> 2.1"
33
32
  spec.add_development_dependency "minitest", "~> 5.0"
34
33
  spec.add_development_dependency "minitest-focus", "~> 1.0"
35
34
  spec.add_development_dependency "rake", "~> 10.0"
@@ -26,7 +26,6 @@ module Gapic
26
26
  ##
27
27
  # Create a new file formatter object
28
28
  #
29
- # @param path_template [String] The URI path template to be parsed.
30
29
  def initialize configuration, files
31
30
  @configuration = configuration
32
31
  @files = format! configuration, files
@@ -40,7 +39,7 @@ module Gapic
40
39
  write_file dir, file
41
40
  end
42
41
 
43
- system "rubocop -x #{dir} -o #{dir}/rubocop.out -c #{configuration}"
42
+ system "rubocop --cache false -x #{dir} -o #{dir}/rubocop.out -c #{configuration}"
44
43
 
45
44
  files.each do |file|
46
45
  read_file dir, file
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Gapic
18
18
  module Generator
19
- VERSION = "0.6.0"
19
+ VERSION = "0.6.5"
20
20
  end
21
21
  end
@@ -14,22 +14,23 @@
14
14
  # See the License for the specific language governing permissions and
15
15
  # limitations under the License.
16
16
 
17
- require "gapic/path_template/parser"
17
+ require "gapic/path_pattern/parser"
18
18
 
19
19
  module Gapic
20
20
  # TODO: Enter docs
21
21
  # Dooooooooocs!!!
22
- module PathTemplate
23
- # Parse a URI path template.
22
+ module PathPattern
23
+ # Parse a URI path pattern.
24
24
  #
25
- # @see https://tools.ietf.org/html/rfc6570 URI Template
25
+ # @see https://google.aip.dev/122 AIP-122 Resource names
26
+ # @see https://google.aip.dev/123 AIP-123 Resource types
26
27
  #
27
- # @param path_template [String] The URI path template to be parsed.
28
+ # @param path_pattern [String] The URI path template to be parsed.
28
29
  #
29
- # @return [Array<PathTemplate::Segment|String>] The segments of the URI
30
+ # @return [PathPattern::Pattern] The parsed pattern
30
31
  # path template.
31
- def self.parse path_template
32
- Parser.new(path_template).segments
32
+ def self.parse path_pattern
33
+ Parser.parse path_pattern
33
34
  end
34
35
  end
35
36
  end
@@ -0,0 +1,146 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2019 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "gapic/path_pattern/segment"
18
+ require "gapic/path_pattern/pattern"
19
+
20
+ module Gapic
21
+ module PathPattern
22
+ ##
23
+ # A path pattern parser.
24
+ # takes a pattern and transforms it into a collection of parsed segments
25
+ # @see https://google.aip.dev/122
26
+ # @see https://google.aip.dev/123
27
+ #
28
+ module Parser
29
+ ##
30
+ # @param path_pattern [String] The path pattern to be parsed
31
+ # @return [Gapic::PathPattern::Pattern]
32
+ def self.parse path_pattern
33
+ remainder = path_pattern.sub(%r{^/}, "").sub(%r{/$}, "")
34
+
35
+ segments = []
36
+ position = 0
37
+ until remainder.empty?
38
+ segment, position, remainder = parse_first_segment_with_position remainder, position
39
+ segments << segment
40
+ end
41
+
42
+ Pattern.new path_pattern, segments
43
+ end
44
+
45
+ # @private
46
+ def self.parse_first_segment_with_position url_pattern, position
47
+ # check for the wildcard segment -- either * or **
48
+ # wildcard segments are positional, so the position counter is used and updated
49
+ segment, remainder = try_capture_wildcard_segment url_pattern, position
50
+ return [segment, position + 1, remainder] if segment
51
+
52
+ # check for the complex resource id segment, e.g. {foo}-{bar}_{baz}
53
+ segment, remainder = try_capture_complex_resource_id_segment url_pattern
54
+ return [segment, position, remainder] if segment
55
+
56
+ # check for the simple resource id segment, e.g. {foo} or {foo=some/pattern/*}
57
+ segment, remainder = try_capture_simple_resource_id_segment url_pattern
58
+ return [segment, position, remainder] if segment
59
+
60
+ # if nothing else fits, it's the collection id segment
61
+ segment, remainder = capture_collection_id_segment url_pattern
62
+ [segment, position, remainder]
63
+ end
64
+
65
+ ##
66
+ # Tries to capture the first segment of the pattern as a wildcard segment
67
+ # The wildcard segment can be either * or **
68
+ # @private
69
+ def self.try_capture_wildcard_segment url_pattern, position
70
+ wildcard_capture_regex = %r{^(?<pattern>\*\*|\*)(?:/|$)}
71
+ return nil, url_pattern unless wildcard_capture_regex.match? url_pattern
72
+
73
+ match = wildcard_capture_regex.match url_pattern
74
+
75
+ wildcard_pattern = match[:pattern]
76
+
77
+ segment = PositionalSegment.new position, wildcard_pattern
78
+ remainder = match.post_match
79
+ [segment, remainder]
80
+ end
81
+
82
+ ##
83
+ # Tries to capture the first segment of the pattern as a complex resource id segment
84
+ # The pattern for the complex resource id segments is:
85
+ # {<name_first>}<separator>{<name_second>} etc, e.g. {foo}-{bar}_{baz}
86
+ # see AIP-4231 Parsing resource names, Complex resource ID path segments
87
+ # @private
88
+ def self.try_capture_complex_resource_id_segment url_pattern
89
+ complex_resource_id_regex =
90
+ %r/^(?<segment_pattern>{(?<name_first>[^\/}]+?)}(?:(?<separator>[_\-~\.]){(?<name_seq>[^\/}]+?)})+)(?:\/|$)/
91
+
92
+ return nil, url_pattern unless complex_resource_id_regex.match? url_pattern
93
+
94
+ match = complex_resource_id_regex.match url_pattern
95
+ segment_pattern = match[:segment_pattern]
96
+
97
+ resource_name_regex = %r/{(?<name>[^\/}]+?)}/
98
+ resource_names = segment_pattern.scan(resource_name_regex).flatten
99
+
100
+ segment = ResourceIdSegment.new :complex_resource_id, segment_pattern, resource_names
101
+ remainder = match.post_match
102
+ [segment, remainder]
103
+ end
104
+
105
+ ##
106
+ # Tries to capture the first segment of the pattern as a simple resource id segment
107
+ # The pattern for the simple resource id segments is:
108
+ # {<name>} or with an optional resource name pattern {<name>=<pattern>}
109
+ # e.g. {foo} or with an optional pattern, e.g. {foo=**} or {foo=bar}
110
+ # notably here the pattern between the = and } *can* contain the path separator /
111
+ # @private
112
+ def self.try_capture_simple_resource_id_segment url_pattern
113
+ simple_resource_id_regex =
114
+ %r/^(?<segment_pattern>{(?<resource_name>[^\/}]+?)(?:=(?<resource_pattern>.+?))?})(?:\/|$)/
115
+ return nil, url_pattern unless simple_resource_id_regex.match? url_pattern
116
+
117
+ match = simple_resource_id_regex.match url_pattern
118
+ segment_pattern = match[:segment_pattern]
119
+
120
+ resource_name = match[:resource_name]
121
+ resource_pattern = match[:resource_pattern] if match.names.include? "resource_pattern"
122
+ resource_patterns = resource_pattern.nil? ? [] : [resource_pattern]
123
+
124
+ segment = ResourceIdSegment.new :simple_resource_id, segment_pattern, [resource_name], resource_patterns
125
+ remainder = match.post_match
126
+ [segment, remainder]
127
+ end
128
+
129
+ ##
130
+ # Captures the first segment of the pattern as a collection id segment
131
+ # This is used as a catch-all, so the collection id segment can contain anything
132
+ # except the path separator /
133
+ # @private
134
+ def self.capture_collection_id_segment url_pattern
135
+ collection_id_regex = %r{^(?<collection_name>[^/]+?)(?:/|$)}
136
+ match = collection_id_regex.match url_pattern
137
+
138
+ collection_name = match[:collection_name]
139
+
140
+ segment = CollectionIdSegment.new collection_name
141
+ remainder = match.post_match
142
+ [segment, remainder]
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2020 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "gapic/path_pattern/segment"
18
+
19
+ module Gapic
20
+ module PathPattern
21
+ ##
22
+ # A parsed pattern.
23
+ # @see https://google.aip.dev/122 AIP-122 Resource names
24
+ # @see https://google.aip.dev/123 AIP-123 Resource types
25
+ #
26
+ # @!attribute [r] path_pattern
27
+ # @return [String] The path pattern
28
+ # @!attribute [r] segments
29
+ # @return [Array<PositionalSegment|ResourceIdSegment|CollectionIdSegment>]
30
+ # The parsed segments of the path pattern
31
+ class Pattern
32
+ attr_reader :path_pattern, :segments
33
+
34
+ def initialize path_pattern, segments
35
+ @path_pattern = path_pattern
36
+ @segments = segments
37
+ end
38
+
39
+ ##
40
+ # All argument names from this pattern
41
+ # @return [Array<String>]
42
+ def arguments
43
+ @segments.select(&:provides_arguments?).map(&:arguments).flatten
44
+ end
45
+
46
+ ##
47
+ # Whether pattern contains a positional segment
48
+ # @return [Boolean]
49
+ def positional_segments?
50
+ @segments.any?(&:positional?)
51
+ end
52
+
53
+ ##
54
+ # Whether pattern contains a segment with a nontrivial resource pattern
55
+ # @return [Boolean]
56
+ def nontrivial_pattern_segments?
57
+ @segments.any?(&:nontrivial_resource_pattern?)
58
+ end
59
+
60
+ ##
61
+ # A template of this pattern - all resource id segments are
62
+ # stripped and replaced by '*'
63
+ # @return [String]
64
+ def template
65
+ @segments.map(&:pattern_template).join("/")
66
+ end
67
+
68
+ ##
69
+ # A parent template to this pattern or an empty string if a pattern
70
+ # can not have a parent (too short)
71
+ # @return [String]
72
+ def parent_template
73
+ return nil if segments.length <= 2
74
+ last_segment = segments.last
75
+ parent_pattern_segments = last_segment.provides_arguments? ? segments[0...-2] : segments[0...-1]
76
+ parent_pattern_segments.map(&:pattern_template).join("/")
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,276 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2019 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Gapic
18
+ module PathPattern
19
+ ##
20
+ # A positional segment in a path pattern.
21
+ # positional segments have a pattern of wildcards and do not carry a name
22
+ #
23
+ # @!attribure [r] type
24
+ # @return [String] The type of this segment
25
+ # @!attribute [r] position
26
+ # @return [Integer] The argument position of this segment i.e.
27
+ # it's position if we remove all non-positional segments from the pattern
28
+ # @!attribute [r] pattern
29
+ # @return [String] The pattern of the segment, for the positional segment it is also
30
+ # a pattern of its resource
31
+ class PositionalSegment
32
+ attr_reader :type, :position, :pattern
33
+ def initialize position, pattern
34
+ @type = :positional
35
+ @position = position
36
+ @pattern = pattern
37
+ end
38
+
39
+ ##
40
+ # Whether the segment is positional
41
+ # @return [Boolean]
42
+ def positional?
43
+ true
44
+ end
45
+
46
+ ##
47
+ # Whether the segment provides a resource pattern
48
+ # @return [Boolean]
49
+ def resource_pattern?
50
+ true
51
+ end
52
+
53
+ ##
54
+ # Whether the segment provides a nontrivial resource pattern
55
+ # @return [Boolean]
56
+ def nontrivial_resource_pattern?
57
+ false
58
+ end
59
+
60
+ ##
61
+ # Whether the segment provides arguments
62
+ # @return [Boolean]
63
+ def provides_arguments?
64
+ true
65
+ end
66
+
67
+ ##
68
+ # Names of the segment's arguments
69
+ # @return [Array<String>]
70
+ def arguments
71
+ [position.to_s]
72
+ end
73
+
74
+ ##
75
+ # Returns a segment's pattern filled with dummy values
76
+ # names of the values are generated starting from the index provided
77
+ # @param start_index [Integer] a starting index for dummy value generation
78
+ # @return [String] a pattern filled with dummy values
79
+ def expected_path_for_dummy_values start_index
80
+ "value#{start_index}"
81
+ end
82
+
83
+ ##
84
+ # Path string for this segment
85
+ # @return [String]
86
+ def path_string
87
+ "\#{#{position}}"
88
+ end
89
+
90
+ ##
91
+ # A pattern template for this segment
92
+ # @return [String]
93
+ def pattern_template
94
+ pattern
95
+ end
96
+
97
+ # @private
98
+ def == other
99
+ return false unless other.is_a? self.class
100
+
101
+ (pattern == other.pattern && position == other.position)
102
+ end
103
+ end
104
+
105
+ # A ResourceId segment in a path pattern.
106
+ # ResourceId segments can be simple, with one resource name
107
+ # or complex, with multiple resource names divided by separators
108
+ #
109
+ # @!attribure [r] type
110
+ # @return [String] The type of this segment
111
+ # @!attribute [r] pattern
112
+ # @return [String] The pattern of the segment, for the positional segment it is also
113
+ # a pattern of its resource
114
+ # @!attribute [r] resource_names
115
+ # @return [Array<String>] The resource names in this segment
116
+ # @!attribute [r] resource_patterns
117
+ # @return [Array<String>] The resource patterns associated with
118
+ # the resource_names of this segment
119
+ class ResourceIdSegment
120
+ attr_reader :type, :pattern, :resource_names, :resource_patterns
121
+
122
+ def initialize type, pattern, resource_names, resource_patterns = []
123
+ @type = type
124
+ @pattern = pattern
125
+ @resource_names = resource_names
126
+ @resource_patterns = resource_patterns
127
+ end
128
+
129
+ ##
130
+ # Whether the segment is positional
131
+ # @return [Boolean]
132
+ def positional?
133
+ false
134
+ end
135
+
136
+ ##
137
+ # Whether the segment provides a resource pattern
138
+ # @return [Boolean]
139
+ def resource_pattern?
140
+ resource_patterns.any?
141
+ end
142
+
143
+ ##
144
+ # Whether the segment provides a nontrivial resource pattern
145
+ # @return [Boolean]
146
+ def nontrivial_resource_pattern?
147
+ resource_patterns.any? { |res_pattern| !res_pattern.match?(/^\*+$/) }
148
+ end
149
+
150
+ ##
151
+ # Whether the segment provides arguments
152
+ # @return [Boolean]
153
+ def provides_arguments?
154
+ true
155
+ end
156
+
157
+ ##
158
+ # Names of the segment's arguments
159
+ # @return [Array<String>]
160
+ def arguments
161
+ resource_names
162
+ end
163
+
164
+ ##
165
+ # Returns a segment's pattern filled with dummy values
166
+ # names of the values are generated starting from the index provided
167
+ # @param start_index [Integer] a starting index for dummy value generation
168
+ # @return [String] a pattern filled with dummy values
169
+ def expected_path_for_dummy_values start_index
170
+ return "value#{start_index}" if type == :simple_resource_id
171
+
172
+ resource_names.each_with_index.reduce pattern do |exp_path, (res_name, index)|
173
+ exp_path.sub "{#{res_name}}", "value#{start_index + index}"
174
+ end
175
+ end
176
+
177
+ ##
178
+ # Path string for this segment
179
+ # @return [String]
180
+ def path_string
181
+ type == :simple_resource_id ? "\#{#{resource_names[0]}}" : pattern.gsub("{", "\#{")
182
+ end
183
+
184
+ ##
185
+ # A pattern template for this segment
186
+ # @return [String]
187
+ def pattern_template
188
+ "*"
189
+ end
190
+
191
+ ##
192
+ # Initialization helper to create a simple resource without a pattern
193
+ # @param name [String] resource name
194
+ # @return [ResourceIdSegment]
195
+ def self.create_simple name
196
+ ResourceIdSegment.new :simple_resource_id, "{#{name}}", [name]
197
+ end
198
+
199
+ # @private
200
+ def == other
201
+ return false unless other.is_a? self.class
202
+
203
+ (type == other.type && pattern == other.pattern &&
204
+ resource_names == other.resource_names &&
205
+ resource_patterns == other.resource_patterns)
206
+ end
207
+ end
208
+
209
+ ##
210
+ # A CollectionId segment in a path template.
211
+ # CollectionId segments are basically string literals
212
+ #
213
+ # @!attribure [r] type
214
+ # @return [String] The type of this segment
215
+ # @!attribute [r] pattern
216
+ # @return [String] The pattern of the segment, for the positional segment it is also
217
+ # a pattern of its resource
218
+ class CollectionIdSegment
219
+ attr_reader :type, :pattern
220
+
221
+ def initialize pattern
222
+ @type = :collection_id
223
+ @pattern = pattern
224
+ end
225
+
226
+ ##
227
+ # Whether the segment is positional
228
+ # @return [Boolean]
229
+ def positional?
230
+ false
231
+ end
232
+
233
+ ##
234
+ # Whether the segment provides a resource pattern
235
+ # @return [Boolean]
236
+ def resource_pattern?
237
+ false
238
+ end
239
+
240
+ ##
241
+ # Whether the segment provides a nontrivial resource pattern
242
+ # @return [Boolean]
243
+ def nontrivial_resource_pattern?
244
+ false
245
+ end
246
+
247
+ ##
248
+ # Whether the segment provides arguments
249
+ # @return [Boolean]
250
+ def provides_arguments?
251
+ false
252
+ end
253
+
254
+ ##
255
+ # Path string for this segment
256
+ # @return [String]
257
+ def path_string
258
+ pattern
259
+ end
260
+
261
+ ##
262
+ # A pattern template for this segment
263
+ # @return [String]
264
+ def pattern_template
265
+ pattern
266
+ end
267
+
268
+ # @private
269
+ def == other
270
+ return false unless other.is_a? self.class
271
+
272
+ (pattern == other.pattern)
273
+ end
274
+ end
275
+ end
276
+ end