optify-config 1.5.0 → 1.7.0

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: b6e408009d1e2d33b018e713943bff39e64af229cd6d01230545049ef4c581f8
4
- data.tar.gz: cab2f82de63a7a1b6b0b2a7be7534ea7d70ff393f127020690ca702193d7721c
3
+ metadata.gz: c39f6b23931576d844b9c6c4991a373f96198f009e4f4a78227adcb373162f2c
4
+ data.tar.gz: 98cd040744bdfeab713795c276b58b472b5e9fff7d4c7bf164f5196aab94e812
5
5
  SHA512:
6
- metadata.gz: 9e53a8589e16df9cfee91990646d719dd39b056f5eb90da8a2ac0f1e4bf9c8b6d5681eab7944d81e650077615fe2d6cee0f214d57f6c1df9d859efc5afedfdf8
7
- data.tar.gz: 7a7c183366b9969a23960c303bcc43004403e34daf5ab7adb06fdfa7dee00d47081950bb58d057a14b1ad14c8d0b1e77aeb919763c921ff26876bdacdc49dbb5
6
+ metadata.gz: b3c2ae32795dbca9e1a9a48eebbec2b6a854e44071554693dbad9c226ec94624cab294b6ed8fa790a0bbd7bbfec5a59bc42cb4d61d475299fde1c41ff0476738
7
+ data.tar.gz: 50bcc0e02ced878b270fd3d98a4f7ba46c66eb67f0b1913429e78ef4362dc30ec9045dc22c00c006424849cfe590b77c8219bac5dd8a6e7a05402f26a966b1c1
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "optify_ruby"
3
- version = "0.9.0"
3
+ version = "0.10.0"
4
4
  edition = "2021"
5
5
 
6
6
  description = "optify bindings for Ruby"
@@ -21,6 +21,6 @@ crate-type = ["cdylib"]
21
21
 
22
22
  [dependencies]
23
23
  magnus = "0.7.1"
24
- optify = { path = "../../../../rust/optify", version = "0.9.0" }
24
+ optify = { path = "../../../../rust/optify", version = "0.10.0" }
25
25
  rb-sys = { version = "*", default-features = false, features = ["ruby-static"] }
26
26
  serde_json = "1.0.140"
@@ -2,7 +2,6 @@ use magnus::{function, method, prelude::*, wrap, Object, Ruby};
2
2
  use optify::builder::OptionsProviderBuilder;
3
3
  use optify::builder::OptionsRegistryBuilder;
4
4
  use optify::builder::OptionsWatcherBuilder;
5
- use optify::convert_to_str_slice;
6
5
  use optify::provider::GetOptionsPreferences;
7
6
  use optify::provider::OptionsProvider;
8
7
  use optify::provider::OptionsRegistry;
@@ -53,6 +52,14 @@ fn convert_metadata(metadata: &OptionsMetadata) -> String {
53
52
  }
54
53
 
55
54
  impl WrappedOptionsProvider {
55
+ fn get_aliases(&self) -> Vec<String> {
56
+ self.0.borrow().get_aliases()
57
+ }
58
+
59
+ fn get_features_and_aliases(&self) -> Vec<String> {
60
+ self.0.borrow().get_features_and_aliases()
61
+ }
62
+
56
63
  // These methods cannot accept `str`s because of how magnus works.
57
64
  // Return the JSON as a string so that it can be deserialized easily into a specific immutable class in Ruby.
58
65
  fn get_all_options_json(
@@ -61,12 +68,11 @@ impl WrappedOptionsProvider {
61
68
  feature_names: Vec<String>,
62
69
  preferences: &MutGetOptionsPreferences,
63
70
  ) -> Result<String, magnus::Error> {
64
- let _preferences = convert_preferences(preferences);
65
- let features = convert_to_str_slice!(feature_names);
71
+ let preferences = convert_preferences(preferences);
66
72
  match rb_self
67
73
  .0
68
74
  .borrow()
69
- .get_all_options(&features, &None, &_preferences)
75
+ .get_all_options(&feature_names, None, Some(&preferences))
70
76
  {
71
77
  Ok(options) => Ok(options.to_string()),
72
78
  Err(e) => Err(magnus::Error::new(ruby.exception_runtime_error(), e)),
@@ -90,11 +96,10 @@ impl WrappedOptionsProvider {
90
96
  rb_self: &Self,
91
97
  feature_names: Vec<String>,
92
98
  ) -> Result<Vec<String>, magnus::Error> {
93
- let features = convert_to_str_slice!(feature_names);
94
99
  rb_self
95
100
  .0
96
101
  .borrow()
97
- .get_canonical_feature_names(&features)
102
+ .get_canonical_feature_names(&feature_names)
98
103
  .map_err(|e| magnus::Error::new(ruby.exception_arg_error(), e))
99
104
  }
100
105
 
@@ -121,11 +126,10 @@ impl WrappedOptionsProvider {
121
126
  key: String,
122
127
  feature_names: Vec<String>,
123
128
  ) -> Result<String, magnus::Error> {
124
- let features = convert_to_str_slice!(feature_names);
125
129
  match rb_self
126
130
  .0
127
131
  .borrow()
128
- .get_options_with_preferences(&key, &features, &None, &None)
132
+ .get_options_with_preferences(&key, &feature_names, None, None)
129
133
  {
130
134
  Ok(options) => Ok(options.to_string()),
131
135
  Err(e) => Err(magnus::Error::new(ruby.exception_runtime_error(), e)),
@@ -139,24 +143,24 @@ impl WrappedOptionsProvider {
139
143
  feature_names: Vec<String>,
140
144
  preferences: &MutGetOptionsPreferences,
141
145
  ) -> Result<String, magnus::Error> {
142
- let _preferences = convert_preferences(preferences);
143
- let features = convert_to_str_slice!(feature_names);
144
- match rb_self
145
- .0
146
- .borrow()
147
- .get_options_with_preferences(&key, &features, &None, &_preferences)
148
- {
146
+ let preferences = convert_preferences(preferences);
147
+ match rb_self.0.borrow().get_options_with_preferences(
148
+ &key,
149
+ &feature_names,
150
+ None,
151
+ Some(&preferences),
152
+ ) {
149
153
  Ok(options) => Ok(options.to_string()),
150
154
  Err(e) => Err(magnus::Error::new(ruby.exception_runtime_error(), e)),
151
155
  }
152
156
  }
153
157
  }
154
158
 
155
- fn convert_preferences(preferences: &MutGetOptionsPreferences) -> Option<GetOptionsPreferences> {
156
- Some(optify::provider::GetOptionsPreferences {
159
+ fn convert_preferences(preferences: &MutGetOptionsPreferences) -> GetOptionsPreferences {
160
+ GetOptionsPreferences {
157
161
  overrides_json: preferences.get_overrides_json(),
158
162
  skip_feature_name_conversion: preferences.skip_feature_name_conversion(),
159
- })
163
+ }
160
164
  }
161
165
 
162
166
  #[derive(Clone)]
@@ -192,18 +196,25 @@ impl WrappedOptionsProviderBuilder {
192
196
  struct WrappedOptionsWatcher(RefCell<OptionsWatcher>);
193
197
 
194
198
  impl WrappedOptionsWatcher {
199
+ fn get_aliases(&self) -> Vec<String> {
200
+ self.0.borrow().get_aliases()
201
+ }
202
+
203
+ fn get_features_and_aliases(&self) -> Vec<String> {
204
+ self.0.borrow().get_features_and_aliases()
205
+ }
206
+
195
207
  fn get_all_options_json(
196
208
  ruby: &Ruby,
197
209
  rb_self: &Self,
198
210
  feature_names: Vec<String>,
199
211
  preferences: &MutGetOptionsPreferences,
200
212
  ) -> Result<String, magnus::Error> {
201
- let _preferences = convert_preferences(preferences);
202
- let features = convert_to_str_slice!(feature_names);
213
+ let preferences = convert_preferences(preferences);
203
214
  match rb_self
204
215
  .0
205
216
  .borrow()
206
- .get_all_options(&features, &None, &_preferences)
217
+ .get_all_options(&feature_names, None, Some(&preferences))
207
218
  {
208
219
  Ok(options) => Ok(options.to_string()),
209
220
  Err(e) => Err(magnus::Error::new(ruby.exception_runtime_error(), e)),
@@ -227,11 +238,10 @@ impl WrappedOptionsWatcher {
227
238
  rb_self: &Self,
228
239
  feature_names: Vec<String>,
229
240
  ) -> Result<Vec<String>, magnus::Error> {
230
- let features = convert_to_str_slice!(feature_names);
231
241
  rb_self
232
242
  .0
233
243
  .borrow()
234
- .get_canonical_feature_names(&features)
244
+ .get_canonical_feature_names(&feature_names)
235
245
  .map_err(|e| magnus::Error::new(ruby.exception_arg_error(), e))
236
246
  }
237
247
 
@@ -256,11 +266,10 @@ impl WrappedOptionsWatcher {
256
266
  key: String,
257
267
  feature_names: Vec<String>,
258
268
  ) -> Result<String, magnus::Error> {
259
- let features = convert_to_str_slice!(feature_names);
260
269
  match rb_self
261
270
  .0
262
271
  .borrow()
263
- .get_options_with_preferences(&key, &features, &None, &None)
272
+ .get_options_with_preferences(&key, &feature_names, None, None)
264
273
  {
265
274
  Ok(options) => Ok(options.to_string()),
266
275
  Err(e) => Err(magnus::Error::new(ruby.exception_runtime_error(), e)),
@@ -274,13 +283,13 @@ impl WrappedOptionsWatcher {
274
283
  feature_names: Vec<String>,
275
284
  preferences: &MutGetOptionsPreferences,
276
285
  ) -> Result<String, magnus::Error> {
277
- let _preferences = convert_preferences(preferences);
278
- let features = convert_to_str_slice!(feature_names);
279
- match rb_self
280
- .0
281
- .borrow()
282
- .get_options_with_preferences(&key, &features, &None, &_preferences)
283
- {
286
+ let preferences = convert_preferences(preferences);
287
+ match rb_self.0.borrow().get_options_with_preferences(
288
+ &key,
289
+ &feature_names,
290
+ None,
291
+ Some(&preferences),
292
+ ) {
284
293
  Ok(options) => Ok(options.to_string()),
285
294
  Err(e) => Err(magnus::Error::new(ruby.exception_runtime_error(), e)),
286
295
  }
@@ -335,7 +344,12 @@ fn init(ruby: &Ruby) -> Result<(), magnus::Error> {
335
344
  builder_class.define_method("build", method!(WrappedOptionsProviderBuilder::build, 0))?;
336
345
 
337
346
  let provider_class = module.define_class("OptionsProvider", ruby.class_object())?;
347
+ provider_class.define_method("aliases", method!(WrappedOptionsProvider::get_aliases, 0))?;
338
348
  provider_class.define_method("features", method!(WrappedOptionsProvider::get_features, 0))?;
349
+ provider_class.define_method(
350
+ "features_and_aliases",
351
+ method!(WrappedOptionsProvider::get_features_and_aliases, 0),
352
+ )?;
339
353
  provider_class.define_method(
340
354
  "get_all_options_json",
341
355
  method!(WrappedOptionsProvider::get_all_options_json, 2),
@@ -405,7 +419,12 @@ fn init(ruby: &Ruby) -> Result<(), magnus::Error> {
405
419
  .define_method("build", method!(WrappedOptionsWatcherBuilder::build, 0))?;
406
420
 
407
421
  let watcher_class = module.define_class("OptionsWatcher", ruby.class_object())?;
422
+ watcher_class.define_method("aliases", method!(WrappedOptionsWatcher::get_aliases, 0))?;
408
423
  watcher_class.define_method("features", method!(WrappedOptionsWatcher::get_features, 0))?;
424
+ watcher_class.define_method(
425
+ "features_and_aliases",
426
+ method!(WrappedOptionsWatcher::get_features_and_aliases, 0),
427
+ )?;
409
428
  watcher_class.define_method(
410
429
  "get_all_options_json",
411
430
  method!(WrappedOptionsWatcher::get_all_options_json, 2),
@@ -8,8 +8,7 @@ module Optify
8
8
  # A base class for classes from configuration files.
9
9
  # Classes that derive from this can easily be used with `Optify::OptionsProvider.get_options`
10
10
  # because they will have an implementation of `from_hash` that works recursively.
11
- # This class is a work in progress with minimal error handling
12
- # and doesn't handle certain cases such as nilable types yet.
11
+ # This class is a work in progress with minimal error handling.
13
12
  # It may be moved to another gem in the future.
14
13
  class BaseConfig
15
14
  extend T::Sig
@@ -26,7 +25,10 @@ module Optify
26
25
  instance = new
27
26
 
28
27
  hash.each do |key, value|
29
- sig_return_type = T::Utils.signature_for_method(instance_method(key)).return_type
28
+ sig = T::Utils.signature_for_method(instance_method(key))
29
+ raise "A Sorbet signature is required for `#{name}.#{key}`." if sig.nil?
30
+
31
+ sig_return_type = sig.return_type
30
32
  value = _convert_value(value, sig_return_type)
31
33
  instance.instance_variable_set("@#{key}", value)
32
34
  end
@@ -104,8 +106,47 @@ module Optify
104
106
  return true if other.equal?(self)
105
107
  return false unless other.is_a?(self.class)
106
108
 
107
- instance_variables.all? do |var|
108
- instance_variable_get(var) == other.instance_variable_get(var)
109
+ instance_variables.all? do |name|
110
+ instance_variable_get(name) == other.instance_variable_get(name)
111
+ end
112
+ end
113
+
114
+ # Convert this object to a Hash recursively.
115
+ # This is mostly the reverse operation of `from_hash`,
116
+ # as keys will be symbols
117
+ # and `from_hash` will convert strings to symbols if that's how the attribute is declared.
118
+ # @return [Hash] The hash representation of this object.
119
+ #: () -> Hash[Symbol, untyped]
120
+ def to_h
121
+ result = Hash.new(instance_variables.size)
122
+
123
+ instance_variables.each do |var_name|
124
+ # Remove the @ prefix to get the method name
125
+ method_name = var_name.to_s[1..] #: as !nil
126
+ value = instance_variable_get(var_name)
127
+ result[method_name.to_sym] = _convert_value_to_hash(value)
128
+ end
129
+
130
+ result
131
+ end
132
+
133
+ private
134
+
135
+ #: (untyped value) -> untyped
136
+ def _convert_value_to_hash(value)
137
+ case value
138
+ when Array
139
+ value.map { |v| _convert_value_to_hash(v) }
140
+ when Hash
141
+ value.transform_values { |v| _convert_value_to_hash(v) }
142
+ when nil
143
+ nil
144
+ else
145
+ if value.respond_to?(:to_h)
146
+ value.to_h
147
+ else
148
+ value
149
+ end
109
150
  end
110
151
  end
111
152
  end
data/rbi/optify.rbi CHANGED
@@ -76,6 +76,14 @@ module Optify
76
76
  class OptionsRegistry
77
77
  abstract!
78
78
 
79
+ # @return All of the aliases.
80
+ sig { returns(T::Array[String]) }
81
+ def aliases; end
82
+
83
+ # @return All of the aliases and features.
84
+ sig { returns(T::Array[String]) }
85
+ def features_and_aliases; end
86
+
79
87
  # @return All of the canonical feature names.
80
88
  sig { returns(T::Array[String]) }
81
89
  def features; end
data/sig/optify.rbs CHANGED
@@ -60,6 +60,12 @@ end
60
60
 
61
61
  # A registry of features that provides configurations.
62
62
  class Optify::OptionsRegistry
63
+ # @return All of the aliases.
64
+ def aliases: () -> ::Array[String]
65
+
66
+ # @return All of the aliases and features.
67
+ def features_and_aliases: () -> ::Array[String]
68
+
63
69
  # @return All of the canonical feature names.
64
70
  def features: () -> ::Array[String]
65
71
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: optify-config
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin D. Harris
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-05-16 00:00:00.000000000 Z
10
+ date: 2025-06-23 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rb_sys
@@ -29,14 +29,14 @@ dependencies:
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: 0.5.12083
32
+ version: 0.5.12167
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 0.5.12083
39
+ version: 0.5.12167
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: rake-compiler
42
42
  requirement: !ruby/object:Gem::Requirement
@@ -57,42 +57,42 @@ dependencies:
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: 3.9.3
60
+ version: 4.0.0.dev.4
61
61
  type: :development
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: 3.9.3
67
+ version: 4.0.0.dev.4
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: sorbet
70
70
  requirement: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: 0.5.12083
74
+ version: 0.5.12167
75
75
  type: :development
76
76
  prerelease: false
77
77
  version_requirements: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: 0.5.12083
81
+ version: 0.5.12167
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: tapioca
84
84
  requirement: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: 0.16.11
88
+ version: 0.17.2
89
89
  type: :development
90
90
  prerelease: false
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: 0.16.11
95
+ version: 0.17.2
96
96
  - !ruby/object:Gem::Dependency
97
97
  name: test-unit
98
98
  requirement: !ruby/object:Gem::Requirement