brand.dev 0.0.2 → 0.1.0.pre.alpha.1

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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -173
  3. data/README.md +1 -1
  4. data/lib/brand_dev/errors.rb +0 -22
  5. data/lib/brand_dev/internal/transport/base_client.rb +2 -10
  6. data/lib/brand_dev/internal/type/array_of.rb +1 -6
  7. data/lib/brand_dev/internal/type/base_model.rb +25 -77
  8. data/lib/brand_dev/internal/type/boolean.rb +1 -7
  9. data/lib/brand_dev/internal/type/converter.rb +34 -42
  10. data/lib/brand_dev/internal/type/enum.rb +5 -16
  11. data/lib/brand_dev/internal/type/file_input.rb +1 -6
  12. data/lib/brand_dev/internal/type/hash_of.rb +1 -6
  13. data/lib/brand_dev/internal/type/union.rb +9 -17
  14. data/lib/brand_dev/internal/type/unknown.rb +1 -7
  15. data/lib/brand_dev/internal/util.rb +9 -8
  16. data/lib/brand_dev/models/brand_ai_query_params.rb +5 -87
  17. data/lib/brand_dev/models/brand_identify_from_transaction_params.rb +1 -14
  18. data/lib/brand_dev/models/brand_identify_from_transaction_response.rb +29 -1
  19. data/lib/brand_dev/models/brand_retrieve_by_ticker_params.rb +1 -14
  20. data/lib/brand_dev/models/brand_retrieve_by_ticker_response.rb +29 -1
  21. data/lib/brand_dev/models/brand_retrieve_naics_params.rb +1 -11
  22. data/lib/brand_dev/models/brand_retrieve_params.rb +1 -24
  23. data/lib/brand_dev/models/brand_retrieve_response.rb +29 -1
  24. data/lib/brand_dev/models/brand_search_params.rb +22 -0
  25. data/lib/brand_dev/models/brand_search_response.rb +35 -0
  26. data/lib/brand_dev/models.rb +5 -11
  27. data/lib/brand_dev/resources/brand.rb +20 -139
  28. data/lib/brand_dev/version.rb +1 -1
  29. data/lib/brand_dev.rb +2 -8
  30. data/rbi/brand_dev/errors.rbi +0 -16
  31. data/rbi/brand_dev/internal/type/boolean.rbi +0 -2
  32. data/rbi/brand_dev/internal/type/converter.rbi +15 -15
  33. data/rbi/brand_dev/internal/type/union.rbi +0 -5
  34. data/rbi/brand_dev/internal/type/unknown.rbi +0 -2
  35. data/rbi/brand_dev/internal/util.rbi +0 -2
  36. data/rbi/brand_dev/models/brand_ai_query_params.rbi +6 -141
  37. data/rbi/brand_dev/models/brand_identify_from_transaction_params.rbi +0 -15
  38. data/rbi/brand_dev/models/brand_identify_from_transaction_response.rbi +69 -0
  39. data/rbi/brand_dev/models/brand_retrieve_by_ticker_params.rbi +1 -19
  40. data/rbi/brand_dev/models/brand_retrieve_by_ticker_response.rbi +69 -0
  41. data/rbi/brand_dev/models/brand_retrieve_naics_params.rbi +1 -19
  42. data/rbi/brand_dev/models/brand_retrieve_params.rbi +0 -30
  43. data/rbi/brand_dev/models/brand_retrieve_response.rbi +65 -0
  44. data/rbi/brand_dev/models/brand_search_params.rbi +40 -0
  45. data/rbi/brand_dev/models/brand_search_response.rbi +63 -0
  46. data/rbi/brand_dev/models.rbi +1 -8
  47. data/rbi/brand_dev/resources/brand.rbi +8 -112
  48. data/sig/brand_dev/errors.rbs +0 -9
  49. data/sig/brand_dev/internal/type/converter.rbs +1 -7
  50. data/sig/brand_dev/models/brand_ai_query_params.rbs +5 -82
  51. data/sig/brand_dev/models/brand_identify_from_transaction_params.rbs +1 -7
  52. data/sig/brand_dev/models/brand_identify_from_transaction_response.rbs +25 -0
  53. data/sig/brand_dev/models/brand_retrieve_by_ticker_params.rbs +1 -8
  54. data/sig/brand_dev/models/brand_retrieve_by_ticker_response.rbs +25 -0
  55. data/sig/brand_dev/models/brand_retrieve_naics_params.rbs +1 -8
  56. data/sig/brand_dev/models/brand_retrieve_params.rbs +1 -15
  57. data/sig/brand_dev/models/brand_retrieve_response.rbs +25 -0
  58. data/sig/brand_dev/models/brand_search_params.rbs +23 -0
  59. data/sig/brand_dev/models/brand_search_response.rbs +29 -0
  60. data/sig/brand_dev/models.rbs +1 -7
  61. data/sig/brand_dev/resources/brand.rbs +4 -29
  62. metadata +10 -28
  63. data/lib/brand_dev/models/brand_prefetch_params.rb +0 -35
  64. data/lib/brand_dev/models/brand_prefetch_response.rb +0 -33
  65. data/lib/brand_dev/models/brand_retrieve_simplified_params.rb +0 -35
  66. data/lib/brand_dev/models/brand_retrieve_simplified_response.rb +0 -280
  67. data/lib/brand_dev/models/brand_screenshot_params.rb +0 -49
  68. data/lib/brand_dev/models/brand_screenshot_response.rb +0 -64
  69. data/lib/brand_dev/models/brand_styleguide_params.rb +0 -36
  70. data/lib/brand_dev/models/brand_styleguide_response.rb +0 -769
  71. data/rbi/brand_dev/models/brand_prefetch_params.rbi +0 -58
  72. data/rbi/brand_dev/models/brand_prefetch_response.rbi +0 -57
  73. data/rbi/brand_dev/models/brand_retrieve_simplified_params.rbi +0 -61
  74. data/rbi/brand_dev/models/brand_retrieve_simplified_response.rbi +0 -667
  75. data/rbi/brand_dev/models/brand_screenshot_params.rbi +0 -105
  76. data/rbi/brand_dev/models/brand_screenshot_response.rbi +0 -135
  77. data/rbi/brand_dev/models/brand_styleguide_params.rbi +0 -60
  78. data/rbi/brand_dev/models/brand_styleguide_response.rbi +0 -1648
  79. data/sig/brand_dev/models/brand_prefetch_params.rbs +0 -30
  80. data/sig/brand_dev/models/brand_prefetch_response.rbs +0 -28
  81. data/sig/brand_dev/models/brand_retrieve_simplified_params.rbs +0 -30
  82. data/sig/brand_dev/models/brand_retrieve_simplified_response.rbs +0 -292
  83. data/sig/brand_dev/models/brand_screenshot_params.rbs +0 -46
  84. data/sig/brand_dev/models/brand_screenshot_response.rbs +0 -63
  85. data/sig/brand_dev/models/brand_styleguide_params.rbs +0 -30
  86. data/sig/brand_dev/models/brand_styleguide_response.rbs +0 -925
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5187a0e7ff93105de03073b21b9af7154630af2e6e27a0f89e6fb00be215f9e
4
- data.tar.gz: d82dc675e43177be3b3027b2b76abdbc858db3ef6552240a8f7aad352eee3532
3
+ metadata.gz: e9985ae9ba5e62a158a02c8cd2b290bab9811c3ebc6f3061c2f1d90cbf2d0dbe
4
+ data.tar.gz: cf66b53c0110ff560bb84484e6113990f4f078aa740ca1a8e653cd32334c6f06
5
5
  SHA512:
6
- metadata.gz: 824254ebd3b93a96f97aa78a39ceb0401563885f5fcf7fea0664afe24b8273627c2bbd47ba717479406e2f5b2b9642ebfd7822f1b0daa41cce06b45053bb1c52
7
- data.tar.gz: 05e67886ddb430d822216bef9baff7168c3a56f49cc625ce55a371c22d0cc61820ac20cc4d42731b7395baac73707389790154e3990778c7f9a8a884daba9ddb
6
+ metadata.gz: d1cdf4ea4e6b14cdf0bd77d0eb0d2a9d75edee737d10d0464f30df495b35e6eb811e55ca8cb1f379c6dd2f109d8052541e7671d0efbcf5cb57f66ca6d53cbfe0
7
+ data.tar.gz: 23b905b672117b2d6ade382f7f0291d800072c1de2967b21f0bde3cad888e5317d87cf42e688697db88d31264c0f70d1eadcee46941c943e4ea171173adf5d39
data/CHANGELOG.md CHANGED
@@ -1,178 +1,5 @@
1
1
  # Changelog
2
2
 
3
- ## 0.0.2 (2025-07-21)
4
-
5
- Full Changelog: [v0.0.1...v0.0.2](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.0.1...v0.0.2)
6
-
7
- ### Chores
8
-
9
- * **internal:** version bump ([c8553b7](https://github.com/brand-dot-dev/ruby-sdk/commit/c8553b728303284cda46b2a980743c5533932fdd))
10
-
11
- ## 0.0.1 (2025-07-21)
12
-
13
- Full Changelog: [v0.1.0-alpha.13...v0.0.1](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.13...v0.0.1)
14
-
15
- ### Features
16
-
17
- * **api:** manual updates ([cfaabba](https://github.com/brand-dot-dev/ruby-sdk/commit/cfaabbab93b68ba4926f78560d759d788e4b4b98))
18
-
19
-
20
- ### Chores
21
-
22
- * **internal:** allow streams to also be unwrapped on a per-row basis ([99d7893](https://github.com/brand-dot-dev/ruby-sdk/commit/99d7893d01a3e111d49fb7c39e53bc9dd524f6b6))
23
- * **internal:** version bump ([d51ca58](https://github.com/brand-dot-dev/ruby-sdk/commit/d51ca5841eb432576fb2e251d4ebdab02cfb1ad7))
24
-
25
- ## 0.1.0-alpha.13 (2025-06-29)
26
-
27
- Full Changelog: [v0.1.0-alpha.12...v0.1.0-alpha.13](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.12...v0.1.0-alpha.13)
28
-
29
- ### Chores
30
-
31
- * **internal:** version bump ([20129a5](https://github.com/brand-dot-dev/ruby-sdk/commit/20129a56c65cbf2bbe2e6f15ea146213a0b41aa0))
32
-
33
- ## 0.1.0-alpha.12 (2025-06-29)
34
-
35
- Full Changelog: [v0.1.0-alpha.11...v0.1.0-alpha.12](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.11...v0.1.0-alpha.12)
36
-
37
- ### Features
38
-
39
- * **api:** manual updates ([ed09624](https://github.com/brand-dot-dev/ruby-sdk/commit/ed09624d1e608e9a6f1294f385341483d4973a3e))
40
-
41
-
42
- ### Chores
43
-
44
- * **ci:** only run for pushes and fork pull requests ([4356075](https://github.com/brand-dot-dev/ruby-sdk/commit/4356075a3db29b2d44ea84ad3abfc37491ec7301))
45
- * **internal:** version bump ([d186e95](https://github.com/brand-dot-dev/ruby-sdk/commit/d186e95c03f25e3f0c07a43e0dab6c40970769e4))
46
-
47
- ## 0.1.0-alpha.11 (2025-06-27)
48
-
49
- Full Changelog: [v0.1.0-alpha.10...v0.1.0-alpha.11](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.10...v0.1.0-alpha.11)
50
-
51
- ### Bug Fixes
52
-
53
- * **ci:** release-doctor — report correct token name ([d8ea78e](https://github.com/brand-dot-dev/ruby-sdk/commit/d8ea78ebf0d975cac2720b3441e4cc98e49e348c))
54
-
55
-
56
- ### Chores
57
-
58
- * **internal:** version bump ([41f18be](https://github.com/brand-dot-dev/ruby-sdk/commit/41f18bedff6bd714f0679df48e7b23e0995916ce))
59
-
60
- ## 0.1.0-alpha.10 (2025-06-19)
61
-
62
- Full Changelog: [v0.1.0-alpha.9...v0.1.0-alpha.10](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.9...v0.1.0-alpha.10)
63
-
64
- ### Features
65
-
66
- * **api:** manual updates ([7d6d67c](https://github.com/brand-dot-dev/ruby-sdk/commit/7d6d67c7b7a3159e7793e2032dd49f9fe491ecce))
67
-
68
-
69
- ### Chores
70
-
71
- * **internal:** version bump ([1cd51db](https://github.com/brand-dot-dev/ruby-sdk/commit/1cd51dbfd4ecb991f8513c180db3eb2b9f8d4a94))
72
-
73
- ## 0.1.0-alpha.9 (2025-06-19)
74
-
75
- Full Changelog: [v0.1.0-alpha.8...v0.1.0-alpha.9](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.8...v0.1.0-alpha.9)
76
-
77
- ### Features
78
-
79
- * **api:** manual updates ([169c21b](https://github.com/brand-dot-dev/ruby-sdk/commit/169c21b016f153befa54e0d2a68fbe0a8fe6df7e))
80
- * **api:** manual updates ([e3f5264](https://github.com/brand-dot-dev/ruby-sdk/commit/e3f5264df830ac3cc62db19ba13050d7822f0259))
81
-
82
-
83
- ### Bug Fixes
84
-
85
- * issue where we cannot mutate arrays on base model derivatives ([ebaaa42](https://github.com/brand-dot-dev/ruby-sdk/commit/ebaaa42de2ed5b3f20120dcba81a42e85cba778a))
86
-
87
-
88
- ### Chores
89
-
90
- * **ci:** enable for pull requests ([1e06613](https://github.com/brand-dot-dev/ruby-sdk/commit/1e066138d45a47d25eaf469e9a472279252ada3a))
91
- * **internal:** version bump ([90fada6](https://github.com/brand-dot-dev/ruby-sdk/commit/90fada6f55ae8d314784042718e7de258694575b))
92
-
93
- ## 0.1.0-alpha.8 (2025-06-12)
94
-
95
- Full Changelog: [v0.1.0-alpha.7...v0.1.0-alpha.8](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.7...v0.1.0-alpha.8)
96
-
97
- ### Chores
98
-
99
- * **ci:** link to correct github repo ([f6c0a8c](https://github.com/brand-dot-dev/ruby-sdk/commit/f6c0a8c7bfa4a6354bec596cca3b8484797bb296))
100
- * **internal:** version bump ([1094c6a](https://github.com/brand-dot-dev/ruby-sdk/commit/1094c6ac192a8b7fe3d774e5fe2d9890fdbc9062))
101
-
102
- ## 0.1.0-alpha.7 (2025-06-08)
103
-
104
- Full Changelog: [v0.1.0-alpha.6...v0.1.0-alpha.7](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.6...v0.1.0-alpha.7)
105
-
106
- ### Chores
107
-
108
- * **internal:** version bump ([d704a75](https://github.com/brand-dot-dev/ruby-sdk/commit/d704a75754d47d3ffa7797e96ae02cc4145b7b59))
109
-
110
- ## 0.1.0-alpha.6 (2025-06-08)
111
-
112
- Full Changelog: [v0.1.0-alpha.5...v0.1.0-alpha.6](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.5...v0.1.0-alpha.6)
113
-
114
- ### Features
115
-
116
- * **api:** manual updates ([aa20a00](https://github.com/brand-dot-dev/ruby-sdk/commit/aa20a0054ed6afaea030f1391f50b94b9e019b17))
117
-
118
-
119
- ### Chores
120
-
121
- * **internal:** version bump ([223cabb](https://github.com/brand-dot-dev/ruby-sdk/commit/223cabb690bebf1e41c54c6cc1c3367b81d9bb98))
122
-
123
- ## 0.1.0-alpha.5 (2025-06-06)
124
-
125
- Full Changelog: [v0.1.0-alpha.4...v0.1.0-alpha.5](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.4...v0.1.0-alpha.5)
126
-
127
- ### Features
128
-
129
- * **api:** manual updates ([d07e957](https://github.com/brand-dot-dev/ruby-sdk/commit/d07e957a8e10c10626468008285953a205b6dafc))
130
-
131
-
132
- ### Chores
133
-
134
- * **internal:** version bump ([6b3a243](https://github.com/brand-dot-dev/ruby-sdk/commit/6b3a2437ab0592fee82bc4829e048937f54d9e18))
135
-
136
- ## 0.1.0-alpha.4 (2025-06-06)
137
-
138
- Full Changelog: [v0.1.0-alpha.3...v0.1.0-alpha.4](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.3...v0.1.0-alpha.4)
139
-
140
- ### Features
141
-
142
- * **api:** manual updates ([05a611f](https://github.com/brand-dot-dev/ruby-sdk/commit/05a611fe140468f965dbb41c0d8250d3dd84a9aa))
143
-
144
-
145
- ### Chores
146
-
147
- * **internal:** codegen related update ([b850fe2](https://github.com/brand-dot-dev/ruby-sdk/commit/b850fe270f6c9e7d63b380a6bdcdb9c0c6b6b65f))
148
-
149
- ## 0.1.0-alpha.3 (2025-06-06)
150
-
151
- Full Changelog: [v0.1.0-alpha.2...v0.1.0-alpha.3](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.2...v0.1.0-alpha.3)
152
-
153
- ### Features
154
-
155
- * **api:** manual updates ([7410667](https://github.com/brand-dot-dev/ruby-sdk/commit/7410667d18ceacfb171c91eb14a4825f77e3487b))
156
-
157
-
158
- ### Chores
159
-
160
- * **internal:** codegen related update ([08a0fc4](https://github.com/brand-dot-dev/ruby-sdk/commit/08a0fc45756634925a18266d526b41a217b37492))
161
-
162
- ## 0.1.0-alpha.2 (2025-06-05)
163
-
164
- Full Changelog: [v0.1.0-alpha.1...v0.1.0-alpha.2](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.1.0-alpha.1...v0.1.0-alpha.2)
165
-
166
- ### Features
167
-
168
- * **api:** manual updates ([6613bcd](https://github.com/brand-dot-dev/ruby-sdk/commit/6613bcdddf846a0dbcb1e507da7ec58c93e4125d))
169
-
170
-
171
- ### Bug Fixes
172
-
173
- * `to_sorbet_type` should not return branded types ([0047f7c](https://github.com/brand-dot-dev/ruby-sdk/commit/0047f7ce754514e6c5ac04546aa262d1e4df68f5))
174
- * default content-type for text in multi-part formdata uploads should be text/plain ([c39a8a7](https://github.com/brand-dot-dev/ruby-sdk/commit/c39a8a78f5445fa88de3b9f765d6211889ba78ef))
175
-
176
3
  ## 0.1.0-alpha.1 (2025-06-02)
177
4
 
178
5
  Full Changelog: [v0.0.1-alpha.0...v0.1.0-alpha.1](https://github.com/brand-dot-dev/ruby-sdk/compare/v0.0.1-alpha.0...v0.1.0-alpha.1)
data/README.md CHANGED
@@ -15,7 +15,7 @@ To use this gem, install via Bundler by adding the following to your application
15
15
  <!-- x-release-please-start-version -->
16
16
 
17
17
  ```ruby
18
- gem "brand.dev", "~> 0.0.2"
18
+ gem "brand.dev", "~> 0.1.0.pre.alpha.1"
19
19
  ```
20
20
 
21
21
  <!-- x-release-please-end -->
@@ -9,28 +9,6 @@ module BrandDev
9
9
  end
10
10
 
11
11
  class ConversionError < BrandDev::Errors::Error
12
- # @return [StandardError, nil]
13
- def cause = @cause.nil? ? super : @cause
14
-
15
- # @api private
16
- #
17
- # @param on [Class<StandardError>]
18
- # @param method [Symbol]
19
- # @param target [Object]
20
- # @param value [Object]
21
- # @param cause [StandardError, nil]
22
- def initialize(on:, method:, target:, value:, cause: nil)
23
- cls = on.name.split("::").last
24
-
25
- message = [
26
- "Failed to parse #{cls}.#{method} from #{value.class} to #{target.inspect}.",
27
- "To get the unparsed API response, use #{cls}[#{method.inspect}].",
28
- cause && "Cause: #{cause.message}"
29
- ].filter(&:itself).join(" ")
30
-
31
- @cause = cause
32
- super(message)
33
- end
34
12
  end
35
13
 
36
14
  class APIError < BrandDev::Errors::Error
@@ -471,7 +471,6 @@ module BrandDev
471
471
  self.class.validate!(req)
472
472
  model = req.fetch(:model) { BrandDev::Internal::Type::Unknown }
473
473
  opts = req[:options].to_h
474
- unwrap = req[:unwrap]
475
474
  BrandDev::RequestOptions.validate!(opts)
476
475
  request = build_request(req.except(:options), opts)
477
476
  url = request.fetch(:url)
@@ -488,18 +487,11 @@ module BrandDev
488
487
  decoded = BrandDev::Internal::Util.decode_content(response, stream: stream)
489
488
  case req
490
489
  in {stream: Class => st}
491
- st.new(
492
- model: model,
493
- url: url,
494
- status: status,
495
- response: response,
496
- unwrap: unwrap,
497
- stream: decoded
498
- )
490
+ st.new(model: model, url: url, status: status, response: response, stream: decoded)
499
491
  in {page: Class => page}
500
492
  page.new(client: self, req: req, headers: response, page_data: decoded)
501
493
  else
502
- unwrapped = BrandDev::Internal::Util.dig(decoded, unwrap)
494
+ unwrapped = BrandDev::Internal::Util.dig(decoded, req[:unwrap])
503
495
  BrandDev::Internal::Type::Converter.coerce(model, unwrapped)
504
496
  end
505
497
  end
@@ -62,14 +62,10 @@ module BrandDev
62
62
  #
63
63
  # @param state [Hash{Symbol=>Object}] .
64
64
  #
65
- # @option state [Boolean] :translate_names
66
- #
67
- # @option state [Boolean] :strictness
65
+ # @option state [Boolean, :strong] :strictness
68
66
  #
69
67
  # @option state [Hash{Symbol=>Object}] :exactness
70
68
  #
71
- # @option state [Class<StandardError>] :error
72
- #
73
69
  # @option state [Integer] :branched
74
70
  #
75
71
  # @return [Array<Object>, Object]
@@ -78,7 +74,6 @@ module BrandDev
78
74
 
79
75
  unless value.is_a?(Array)
80
76
  exactness[:no] += 1
81
- state[:error] = TypeError.new("#{value.class} can't be coerced into #{Array}")
82
77
  return value
83
78
  end
84
79
 
@@ -60,7 +60,7 @@ module BrandDev
60
60
  [BrandDev::Internal::Type::Converter.type_info(type_info), type_info]
61
61
  end
62
62
 
63
- setter = :"#{name_sym}="
63
+ setter = "#{name_sym}="
64
64
  api_name = info.fetch(:api_name, name_sym)
65
65
  nilable = info.fetch(:nil?, false)
66
66
  const = if required && !nilable
@@ -84,61 +84,30 @@ module BrandDev
84
84
  type_fn: type_fn
85
85
  }
86
86
 
87
- define_method(setter) do |value|
88
- target = type_fn.call
89
- state = BrandDev::Internal::Type::Converter.new_coerce_state(translate_names: false)
90
- coerced = BrandDev::Internal::Type::Converter.coerce(target, value, state: state)
91
- status = @coerced.store(name_sym, state.fetch(:error) || true)
92
- stored =
93
- case [target, status]
94
- in [BrandDev::Internal::Type::Converter | Symbol, true]
95
- coerced
96
- else
97
- value
98
- end
99
- @data.store(name_sym, stored)
100
- end
87
+ define_method(setter) { @data.store(name_sym, _1) }
101
88
 
102
- # rubocop:disable Style/CaseEquality
103
- # rubocop:disable Metrics/BlockLength
104
89
  define_method(name_sym) do
105
90
  target = type_fn.call
106
-
107
- case @coerced[name_sym]
108
- in true | false if BrandDev::Internal::Type::Converter === target
109
- @data.fetch(name_sym)
110
- in ::StandardError => e
111
- raise BrandDev::Errors::ConversionError.new(
112
- on: self.class,
113
- method: __method__,
114
- target: target,
115
- value: @data.fetch(name_sym),
116
- cause: e
117
- )
91
+ value = @data.fetch(name_sym) { const == BrandDev::Internal::OMIT ? nil : const }
92
+ state = {strictness: :strong, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0}
93
+ if (nilable || !required) && value.nil?
94
+ nil
118
95
  else
119
- Kernel.then do
120
- value = @data.fetch(name_sym) { const == BrandDev::Internal::OMIT ? nil : const }
121
- state = BrandDev::Internal::Type::Converter.new_coerce_state(translate_names: false)
122
- if (nilable || !required) && value.nil?
123
- nil
124
- else
125
- BrandDev::Internal::Type::Converter.coerce(
126
- target, value, state: state
127
- )
128
- end
129
- rescue StandardError => e
130
- raise BrandDev::Errors::ConversionError.new(
131
- on: self.class,
132
- method: __method__,
133
- target: target,
134
- value: value,
135
- cause: e
136
- )
137
- end
96
+ BrandDev::Internal::Type::Converter.coerce(
97
+ target,
98
+ value,
99
+ state: state
100
+ )
138
101
  end
102
+ rescue StandardError => e
103
+ cls = self.class.name.split("::").last
104
+ message = [
105
+ "Failed to parse #{cls}.#{__method__} from #{value.class} to #{target.inspect}.",
106
+ "To get the unparsed API response, use #{cls}[#{__method__.inspect}].",
107
+ "Cause: #{e.message}"
108
+ ].join(" ")
109
+ raise BrandDev::Errors::ConversionError.new(message)
139
110
  end
140
- # rubocop:enable Metrics/BlockLength
141
- # rubocop:enable Style/CaseEquality
142
111
  end
143
112
 
144
113
  # @api private
@@ -238,28 +207,23 @@ module BrandDev
238
207
  #
239
208
  # @param state [Hash{Symbol=>Object}] .
240
209
  #
241
- # @option state [Boolean] :translate_names
242
- #
243
- # @option state [Boolean] :strictness
210
+ # @option state [Boolean, :strong] :strictness
244
211
  #
245
212
  # @option state [Hash{Symbol=>Object}] :exactness
246
213
  #
247
- # @option state [Class<StandardError>] :error
248
- #
249
214
  # @option state [Integer] :branched
250
215
  #
251
216
  # @return [self, Object]
252
217
  def coerce(value, state:)
253
218
  exactness = state.fetch(:exactness)
254
219
 
255
- if value.is_a?(self)
220
+ if value.is_a?(self.class)
256
221
  exactness[:yes] += 1
257
222
  return value
258
223
  end
259
224
 
260
225
  unless (val = BrandDev::Internal::Util.coerce_hash(value)).is_a?(Hash)
261
226
  exactness[:no] += 1
262
- state[:error] = TypeError.new("#{value.class} can't be coerced into #{Hash}")
263
227
  return value
264
228
  end
265
229
  exactness[:yes] += 1
@@ -267,15 +231,13 @@ module BrandDev
267
231
  keys = val.keys.to_set
268
232
  instance = new
269
233
  data = instance.to_h
270
- status = instance.instance_variable_get(:@coerced)
271
234
 
272
235
  # rubocop:disable Metrics/BlockLength
273
236
  fields.each do |name, field|
274
237
  mode, required, target = field.fetch_values(:mode, :required, :type)
275
238
  api_name, nilable, const = field.fetch_values(:api_name, :nilable, :const)
276
- src_name = state.fetch(:translate_names) ? api_name : name
277
239
 
278
- unless val.key?(src_name)
240
+ unless val.key?(api_name)
279
241
  if required && mode != :dump && const == BrandDev::Internal::OMIT
280
242
  exactness[nilable ? :maybe : :no] += 1
281
243
  else
@@ -284,10 +246,9 @@ module BrandDev
284
246
  next
285
247
  end
286
248
 
287
- item = val.fetch(src_name)
288
- keys.delete(src_name)
249
+ item = val.fetch(api_name)
250
+ keys.delete(api_name)
289
251
 
290
- state[:error] = nil
291
252
  converted =
292
253
  if item.nil? && (nilable || !required)
293
254
  exactness[nilable ? :yes : :maybe] += 1
@@ -301,8 +262,6 @@ module BrandDev
301
262
  item
302
263
  end
303
264
  end
304
-
305
- status.store(name, state.fetch(:error) || true)
306
265
  data.store(name, converted)
307
266
  end
308
267
  # rubocop:enable Metrics/BlockLength
@@ -478,18 +437,7 @@ module BrandDev
478
437
  # Create a new instance of a model.
479
438
  #
480
439
  # @param data [Hash{Symbol=>Object}, self]
481
- def initialize(data = {})
482
- @data = {}
483
- @coerced = {}
484
- BrandDev::Internal::Util.coerce_hash!(data).each do
485
- if self.class.known_fields.key?(_1)
486
- public_send(:"#{_1}=", _2)
487
- else
488
- @data.store(_1, _2)
489
- @coerced.store(_1, false)
490
- end
491
- end
492
- end
440
+ def initialize(data = {}) = (@data = BrandDev::Internal::Util.coerce_hash!(data).to_h)
493
441
 
494
442
  class << self
495
443
  # @api private
@@ -31,20 +31,14 @@ module BrandDev
31
31
  class << self
32
32
  # @api private
33
33
  #
34
- # Coerce value to Boolean if possible, otherwise return the original value.
35
- #
36
34
  # @param value [Boolean, Object]
37
35
  #
38
36
  # @param state [Hash{Symbol=>Object}] .
39
37
  #
40
- # @option state [Boolean] :translate_names
41
- #
42
- # @option state [Boolean] :strictness
38
+ # @option state [Boolean, :strong] :strictness
43
39
  #
44
40
  # @option state [Hash{Symbol=>Object}] :exactness
45
41
  #
46
- # @option state [Class<StandardError>] :error
47
- #
48
42
  # @option state [Integer] :branched
49
43
  #
50
44
  # @return [Boolean, Object]
@@ -15,14 +15,10 @@ module BrandDev
15
15
  #
16
16
  # @param state [Hash{Symbol=>Object}] .
17
17
  #
18
- # @option state [Boolean] :translate_names
19
- #
20
- # @option state [Boolean] :strictness
18
+ # @option state [Boolean, :strong] :strictness
21
19
  #
22
20
  # @option state [Hash{Symbol=>Object}] :exactness
23
21
  #
24
- # @option state [Class<StandardError>] :error
25
- #
26
22
  # @option state [Integer] :branched
27
23
  #
28
24
  # @return [Object]
@@ -98,21 +94,6 @@ module BrandDev
98
94
  end
99
95
  end
100
96
 
101
- # @api private
102
- #
103
- # @param translate_names [Boolean]
104
- #
105
- # @return [Hash{Symbol=>Object}]
106
- def new_coerce_state(translate_names: true)
107
- {
108
- translate_names: translate_names,
109
- strictness: true,
110
- exactness: {yes: 0, no: 0, maybe: 0},
111
- error: nil,
112
- branched: 0
113
- }
114
- end
115
-
116
97
  # @api private
117
98
  #
118
99
  # Based on `target`, transform `value` into `target`, to the extent possible:
@@ -129,11 +110,14 @@ module BrandDev
129
110
  #
130
111
  # @param value [Object]
131
112
  #
132
- # @param state [Hash{Symbol=>Object}] The `strictness` is one of `true`, `false`. This informs the coercion strategy
133
- # when we have to decide between multiple possible conversion targets:
113
+ # @param state [Hash{Symbol=>Object}] The `strictness` is one of `true`, `false`, or `:strong`. This informs the
114
+ # coercion strategy when we have to decide between multiple possible conversion
115
+ # targets:
134
116
  #
135
117
  # - `true`: the conversion must be exact, with minimum coercion.
136
118
  # - `false`: the conversion can be approximate, with some coercion.
119
+ # - `:strong`: the conversion must be exact, with no coercion, and raise an error
120
+ # if not possible.
137
121
  #
138
122
  # The `exactness` is `Hash` with keys being one of `yes`, `no`, or `maybe`. For
139
123
  # any given conversion attempt, the exactness will be updated based on how closely
@@ -146,20 +130,21 @@ module BrandDev
146
130
  #
147
131
  # See implementation below for more details.
148
132
  #
149
- # @option state [Boolean] :translate_names
150
- #
151
- # @option state [Boolean] :strictness
133
+ # @option state [Boolean, :strong] :strictness
152
134
  #
153
135
  # @option state [Hash{Symbol=>Object}] :exactness
154
136
  #
155
- # @option state [Class<StandardError>] :error
156
- #
157
137
  # @option state [Integer] :branched
158
138
  #
159
139
  # @return [Object]
160
- def coerce(target, value, state: BrandDev::Internal::Type::Converter.new_coerce_state)
140
+ def coerce(
141
+ target,
142
+ value,
143
+ state: {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0}
144
+ )
145
+ # rubocop:disable Lint/SuppressedException
161
146
  # rubocop:disable Metrics/BlockNesting
162
- exactness = state.fetch(:exactness)
147
+ strictness, exactness = state.fetch_values(:strictness, :exactness)
163
148
 
164
149
  case target
165
150
  in BrandDev::Internal::Type::Converter
@@ -175,26 +160,29 @@ module BrandDev
175
160
  exactness[value.nil? ? :yes : :maybe] += 1
176
161
  return nil
177
162
  in -> { _1 <= Integer }
178
- case value
179
- in Integer
163
+ if value.is_a?(Integer)
180
164
  exactness[:yes] += 1
181
165
  return value
166
+ elsif strictness == :strong && Integer(value, exception: false) != value
167
+ message = "no implicit conversion of #{value.class} into #{target.inspect}"
168
+ raise value.is_a?(Numeric) ? ArgumentError.new(message) : TypeError.new(message)
182
169
  else
183
170
  Kernel.then do
184
171
  return Integer(value).tap { exactness[:maybe] += 1 }
185
- rescue ArgumentError, TypeError => e
186
- state[:error] = e
172
+ rescue ArgumentError, TypeError
187
173
  end
188
174
  end
189
175
  in -> { _1 <= Float }
190
176
  if value.is_a?(Numeric)
191
177
  exactness[:yes] += 1
192
178
  return Float(value)
179
+ elsif strictness == :strong
180
+ message = "no implicit conversion of #{value.class} into #{target.inspect}"
181
+ raise TypeError.new(message)
193
182
  else
194
183
  Kernel.then do
195
184
  return Float(value).tap { exactness[:maybe] += 1 }
196
- rescue ArgumentError, TypeError => e
197
- state[:error] = e
185
+ rescue ArgumentError, TypeError
198
186
  end
199
187
  end
200
188
  in -> { _1 <= String }
@@ -206,13 +194,16 @@ module BrandDev
206
194
  exactness[:yes] += 1
207
195
  return value.string
208
196
  else
209
- state[:error] = TypeError.new("#{value.class} can't be coerced into #{String}")
197
+ if strictness == :strong
198
+ message = "no implicit conversion of #{value.class} into #{target.inspect}"
199
+ raise TypeError.new(message)
200
+ end
210
201
  end
211
202
  in -> { _1 <= Date || _1 <= Time }
212
203
  Kernel.then do
213
204
  return target.parse(value).tap { exactness[:yes] += 1 }
214
205
  rescue ArgumentError, TypeError => e
215
- state[:error] = e
206
+ raise e if strictness == :strong
216
207
  end
217
208
  in -> { _1 <= StringIO } if value.is_a?(String)
218
209
  exactness[:yes] += 1
@@ -230,8 +221,10 @@ module BrandDev
230
221
  return value
231
222
  end
232
223
  else
233
- message = "cannot convert non-matching #{value.class} into #{target.inspect}"
234
- state[:error] = ArgumentError.new(message)
224
+ if strictness == :strong
225
+ message = "cannot convert non-matching #{value.class} into #{target.inspect}"
226
+ raise ArgumentError.new(message)
227
+ end
235
228
  end
236
229
  else
237
230
  end
@@ -239,6 +232,7 @@ module BrandDev
239
232
  exactness[:no] += 1
240
233
  value
241
234
  # rubocop:enable Metrics/BlockNesting
235
+ # rubocop:enable Lint/SuppressedException
242
236
  end
243
237
 
244
238
  # @api private
@@ -283,10 +277,8 @@ module BrandDev
283
277
  define_sorbet_constant!(:CoerceState) do
284
278
  T.type_alias do
285
279
  {
286
- translate_names: T::Boolean,
287
- strictness: T::Boolean,
280
+ strictness: T.any(T::Boolean, Symbol),
288
281
  exactness: {yes: Integer, no: Integer, maybe: Integer},
289
- error: T::Class[StandardError],
290
282
  branched: Integer
291
283
  }
292
284
  end