haveapi-rust-client 0.30.1 → 0.30.2

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: d48abd48b55a176accb7ff4492b9de2e68b6ee4b324d7edb406261387b467c4e
4
- data.tar.gz: 2eb8481e97155eef2b0ad829b135ad504f880a29afea0a5b9e0c157229bb4ea5
3
+ metadata.gz: 96e9f24f598297eaaea7bce5ae34feaad34b8bb8db00af2c854602d686e5c267
4
+ data.tar.gz: 2671a364e42f99c7b44e704820c05653f999fb57844f289e09d7991ccfeb946e
5
5
  SHA512:
6
- metadata.gz: 738bbd676ea82ff0a2eb25898c16a7038c5e8b25b54abaec838a8e1a25de08b248e92af70c355a886439f31572460eece27f8f96aed8630f945b95d554cba500
7
- data.tar.gz: d0aa4952b7baf709927e4f95257ec8a42d72b672ca3f60fb048fcf8ca84f856fd0836a164101be162f69e12a4abaff2d6a4d2234f76e3d8e3d69c8e54d0ce837
6
+ metadata.gz: 821fb5d7d22dd75afe6b5dedbeff675ad7141873fda8af9c7da55b24cc394e2a26bbc96af10d0d1a425249e41d3b12218384d8cfe5f7cf4884826f12129caa73
7
+ data.tar.gz: 450823127999c9458b96607d7f25fae0ec4d49d38857f9d1d157f51aae4dee00ec900a940e2bf74e834a27e78d29b115435a988d80a0a5760bd1e76a35971a98
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../ruby
3
3
  specs:
4
- haveapi-client (0.30.1)
4
+ haveapi-client (0.30.2)
5
5
  activesupport (>= 7.0)
6
6
  highline (~> 3.1)
7
7
  json
@@ -12,9 +12,9 @@ PATH
12
12
  PATH
13
13
  remote: .
14
14
  specs:
15
- haveapi-rust-client (0.30.1)
15
+ haveapi-rust-client (0.30.2)
16
16
  fiddle (~> 1.1, >= 1.1.8)
17
- haveapi-client (~> 0.30.1)
17
+ haveapi-client (~> 0.30.2)
18
18
  tomlrb (~> 2.0)
19
19
 
20
20
  GEM
@@ -137,6 +137,7 @@ PLATFORMS
137
137
  DEPENDENCIES
138
138
  haveapi-client!
139
139
  haveapi-rust-client!
140
+ json (= 2.21.2)
140
141
  rake
141
142
  rspec
142
143
  rubocop (~> 1.85.0)
@@ -155,8 +156,8 @@ CHECKSUMS
155
156
  drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
156
157
  fiddle (1.1.8) sha256=7fa8ee3627271497f3add5503acdbc3f40b32f610fc1cf49634f083ef3f32eee
157
158
  hana (1.3.7) sha256=5425db42d651fea08859811c29d20446f16af196308162894db208cac5ce9b0d
158
- haveapi-client (0.30.1)
159
- haveapi-rust-client (0.30.1)
159
+ haveapi-client (0.30.2)
160
+ haveapi-rust-client (0.30.2)
160
161
  highline (3.1.2) sha256=67cbd34d19f6ef11a7ee1d82ffab5d36dfd5b3be861f450fc1716c7125f4bb4a
161
162
  http-accept (1.7.0) sha256=c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126
162
163
  http-cookie (1.1.6) sha256=ba4b82be64de61dc281243dac70e3c382c45142f20268ed9276a3670c93feaa9
@@ -80,6 +80,20 @@ defaults, local paths and initialization diagnostics never enter rendered output
80
80
  See the [server profile guide](../../../doc/client-examples.md) for compatibility
81
81
  and rollback requirements.
82
82
 
83
+ The adapter selects the action or advertised authentication provider from the
84
+ current authorized description before normalizing that subtree. The private
85
+ saved model resolves SDK names; it cannot establish authorization. Authentication
86
+ still compares the complete supplied provider description with authorized help,
87
+ and action rendering validates live routes and supplied parameter contracts.
88
+ Symbol/string keys retain last-insertion collision behavior. No authorized
89
+ description or rendering decision is cached across contexts or users.
90
+
91
+ Normalization avoids unrelated resource descendants. Ancestor map lookup and
92
+ saved-model action resolution can still depend on sibling/action counts. This
93
+ does not make the complete render operation constant-time. Server context
94
+ derivation shares unchanged owned data, while explicitly supplied resources,
95
+ actions and samples still cross its copying boundary.
96
+
83
97
  The pure in-memory factories use the same resolve/render interface as legacy
84
98
  `Documentation.new(snapshot:, config:)`:
85
99
 
@@ -120,11 +134,21 @@ The pure adapter specs and server renderer bridge specs run before compilation:
120
134
 
121
135
  ```sh
122
136
  nix develop .#client-rust --command bash -c \
123
- 'cd clients/rust && bundle exec rspec spec/unit/documentation_spec.rb spec/unit/documentation_harness_spec.rb'
137
+ 'cd clients/rust && bundle exec rspec spec/unit/documentation_spec.rb spec/unit/documentation_performance_spec.rb spec/unit/documentation_harness_spec.rb'
124
138
  nix develop .#server-ruby --command bash -c \
125
139
  'cd servers/ruby && bundle exec rspec spec/client_examples/rust_client_spec.rb'
126
140
  ```
127
141
 
142
+ The performance unit specs count normalization work around real renders and
143
+ check output/authorization parity as unrelated resource trees grow. They use no
144
+ wall-clock budget. The opt-in [documentation benchmark](../../../doc/client-examples.md#documentation-benchmark)
145
+ adds timing and allocation evidence. With server and Rust generator Ruby
146
+ dependencies prepared, pass `--rust` through `BENCHMARK_DOCUMENTATION_ARGS` to
147
+ include a matching profile in HTML and measure async/blocking adapter action and
148
+ authentication rendering separately. These lanes do not generate or compile an
149
+ SDK. Compare the same fixture, runtime, dependency inputs and output digests
150
+ against both implementation revisions before claiming a measured improvement.
151
+
128
152
  The acceptance runner extracts actual `RustAsyncClient.render` and
129
153
  `RustBlockingClient.render` source. It generates a matching temporary fixture
130
154
  SDK, compiles the emitted imports, paths, methods and types, and executes the
@@ -116,6 +116,11 @@ module HaveAPI::RustClient
116
116
  end
117
117
  end
118
118
 
119
+ # Match normalize's last-insertion key semantics without visiting descendants.
120
+ def normalized_members(value)
121
+ value.is_a?(Hash) ? value.to_h { |key, item| [key.to_s, item] } : {}
122
+ end
123
+
119
124
  def program(context, mode, body, credentials: [])
120
125
  dependencies = dependency_lines(mode)
121
126
  dependencies << '// cargo add tokio --features macros,rt-multi-thread' if mode == :async
@@ -146,9 +151,13 @@ module HaveAPI::RustClient
146
151
 
147
152
  def authentication(context, mode, method, description)
148
153
  provider = method.to_s
149
- live = normalize(context.description).fetch('authentication', {})[provider]
154
+ providers = normalized_members(context.description)['authentication']
155
+ live = normalized_members(providers)[provider]
150
156
  saved = @snapshot.fetch('description').fetch('authentication')[provider]
151
- unsupported!('This authentication provider is unavailable in the authorized Rust SDK profile.') unless live && saved
157
+ unless live.is_a?(Hash) && saved
158
+ unsupported!('This authentication provider is unavailable in the authorized Rust SDK profile.')
159
+ end
160
+ live = normalize(live)
152
161
  unsupported!('The authentication description differs from the authorized help.') unless normalize(description) == live
153
162
 
154
163
  credentials = case provider
@@ -206,14 +215,16 @@ module HaveAPI::RustClient
206
215
  def action_credentials(action, context)
207
216
  return [] if action[:desc]['auth'] == false
208
217
 
209
- live = normalize(context.description).fetch('authentication', {})
218
+ live = normalized_members(normalized_members(context.description)['authentication'])
210
219
  saved = @snapshot.fetch('description').fetch('authentication')
211
220
  if live.has_key?('basic') && saved.has_key?('basic')
212
221
  return ['.basic_auth(std::env::var("HAVEAPI_USER")?, std::env::var("HAVEAPI_PASSWORD")?)']
213
222
  end
214
223
 
215
224
  %w[token oauth2].each do |provider|
216
- next unless live[provider] && saved[provider] && live[provider]['http_header'] == saved[provider]['http_header']
225
+ advertised = live[provider]
226
+ next unless advertised.is_a?(Hash) && saved[provider]
227
+ next unless normalize(normalized_members(advertised)['http_header']) == saved[provider]['http_header']
217
228
 
218
229
  setter = provider == 'token' ? 'token' : 'oauth2_token'
219
230
  return [".#{setter}(std::env::var(\"HAVEAPI_TOKEN\")?)"]
@@ -222,15 +233,16 @@ module HaveAPI::RustClient
222
233
  end
223
234
 
224
235
  def authorized_action(context)
225
- resources = normalize(context.description).fetch('resources', {})
236
+ resources = normalized_members(context.description)['resources']
226
237
  resource = nil
227
238
  context.resource_path.each do |name|
228
- resource = resources[name.to_s]
229
- return nil unless resource
239
+ resource = normalized_members(resources)[name.to_s]
240
+ return nil unless resource.is_a?(Hash)
230
241
 
231
- resources = resource.fetch('resources', {})
242
+ resources = normalized_members(resource)['resources']
232
243
  end
233
- resource && resource.fetch('actions', {})[context.action_name.to_s]
244
+ action = normalized_members(normalized_members(resource)['actions'])[context.action_name.to_s]
245
+ normalize(action) if action.is_a?(Hash)
234
246
  end
235
247
 
236
248
  def compatible_action!(saved, live, context)
@@ -1,5 +1,5 @@
1
1
  module HaveAPI
2
2
  module RustClient
3
- VERSION = '0.30.1'.freeze
3
+ VERSION = '0.30.2'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haveapi-rust-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.30.1
4
+ version: 0.30.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jakub Skokan
@@ -35,14 +35,14 @@ dependencies:
35
35
  requirements:
36
36
  - - "~>"
37
37
  - !ruby/object:Gem::Version
38
- version: 0.30.1
38
+ version: 0.30.2
39
39
  type: :runtime
40
40
  prerelease: false
41
41
  version_requirements: !ruby/object:Gem::Requirement
42
42
  requirements:
43
43
  - - "~>"
44
44
  - !ruby/object:Gem::Version
45
- version: 0.30.1
45
+ version: 0.30.2
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: tomlrb
48
48
  requirement: !ruby/object:Gem::Requirement