finch-api 0.1.0.pre.alpha.3 → 0.1.0.pre.alpha.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 (211) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -8
  3. data/lib/finch-api/client.rb +1 -1
  4. data/lib/finch-api/individuals_page.rb +4 -4
  5. data/lib/finch-api/models/access_token_create_params.rb +1 -1
  6. data/lib/finch-api/models/account_disconnect_params.rb +1 -1
  7. data/lib/finch-api/models/account_introspect_params.rb +1 -1
  8. data/lib/finch-api/models/connect/session_new_params.rb +1 -1
  9. data/lib/finch-api/models/connect/session_reauthenticate_params.rb +1 -1
  10. data/lib/finch-api/models/hris/benefit_create_params.rb +1 -1
  11. data/lib/finch-api/models/hris/benefit_list_params.rb +1 -1
  12. data/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rb +1 -1
  13. data/lib/finch-api/models/hris/benefit_retrieve_params.rb +1 -1
  14. data/lib/finch-api/models/hris/benefit_update_params.rb +1 -1
  15. data/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rb +1 -1
  16. data/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rb +1 -1
  17. data/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rb +1 -1
  18. data/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rb +1 -1
  19. data/lib/finch-api/models/hris/company_retrieve_params.rb +1 -1
  20. data/lib/finch-api/models/hris/directory_list_individuals_params.rb +1 -1
  21. data/lib/finch-api/models/hris/directory_list_params.rb +1 -1
  22. data/lib/finch-api/models/hris/document_list_params.rb +1 -1
  23. data/lib/finch-api/models/hris/document_retreive_params.rb +1 -1
  24. data/lib/finch-api/models/hris/employment_retrieve_many_params.rb +1 -1
  25. data/lib/finch-api/models/hris/individual_retrieve_many_params.rb +1 -1
  26. data/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rb +1 -1
  27. data/lib/finch-api/models/hris/payment_list_params.rb +1 -1
  28. data/lib/finch-api/models/introspection.rb +12 -1
  29. data/lib/finch-api/models/jobs/automated_create_params.rb +1 -1
  30. data/lib/finch-api/models/jobs/automated_list_params.rb +1 -1
  31. data/lib/finch-api/models/jobs/automated_retrieve_params.rb +1 -1
  32. data/lib/finch-api/models/jobs/manual_retrieve_params.rb +1 -1
  33. data/lib/finch-api/models/payroll/pay_group_list_params.rb +1 -1
  34. data/lib/finch-api/models/payroll/pay_group_retrieve_params.rb +1 -1
  35. data/lib/finch-api/models/provider_list_params.rb +1 -1
  36. data/lib/finch-api/models/request_forwarding_forward_params.rb +1 -1
  37. data/lib/finch-api/models/sandbox/company_update_params.rb +1 -1
  38. data/lib/finch-api/models/sandbox/connection_create_params.rb +1 -1
  39. data/lib/finch-api/models/sandbox/connections/account_create_params.rb +1 -1
  40. data/lib/finch-api/models/sandbox/connections/account_update_params.rb +1 -1
  41. data/lib/finch-api/models/sandbox/directory_create_params.rb +1 -1
  42. data/lib/finch-api/models/sandbox/employment_update_params.rb +1 -1
  43. data/lib/finch-api/models/sandbox/individual_update_params.rb +1 -1
  44. data/lib/finch-api/models/sandbox/job_create_params.rb +1 -1
  45. data/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rb +1 -1
  46. data/lib/finch-api/models/sandbox/jobs/configuration_update_params.rb +1 -1
  47. data/lib/finch-api/models/sandbox/payment_create_params.rb +1 -1
  48. data/lib/finch-api/page.rb +4 -4
  49. data/lib/finch-api/request_options.rb +0 -33
  50. data/lib/finch-api/responses_page.rb +3 -3
  51. data/lib/finch-api/single_page.rb +3 -3
  52. data/lib/finch-api/transport/base_client.rb +459 -0
  53. data/lib/finch-api/transport/pooled_net_requester.rb +182 -0
  54. data/lib/finch-api/type/array_of.rb +110 -0
  55. data/lib/finch-api/type/base_model.rb +355 -0
  56. data/lib/finch-api/type/base_page.rb +61 -0
  57. data/lib/finch-api/type/boolean_model.rb +52 -0
  58. data/lib/finch-api/type/converter.rb +211 -0
  59. data/lib/finch-api/type/enum.rb +105 -0
  60. data/lib/finch-api/type/hash_of.rb +136 -0
  61. data/lib/finch-api/type/request_parameters.rb +38 -0
  62. data/lib/finch-api/type/union.rb +204 -0
  63. data/lib/finch-api/type/unknown.rb +56 -0
  64. data/lib/finch-api/type.rb +23 -0
  65. data/lib/finch-api/util.rb +3 -5
  66. data/lib/finch-api/version.rb +1 -1
  67. data/lib/finch-api.rb +13 -5
  68. data/rbi/lib/finch-api/client.rbi +1 -1
  69. data/rbi/lib/finch-api/individuals_page.rbi +1 -1
  70. data/rbi/lib/finch-api/models/access_token_create_params.rbi +1 -1
  71. data/rbi/lib/finch-api/models/account_disconnect_params.rbi +1 -1
  72. data/rbi/lib/finch-api/models/account_introspect_params.rbi +1 -1
  73. data/rbi/lib/finch-api/models/connect/session_new_params.rbi +1 -1
  74. data/rbi/lib/finch-api/models/connect/session_reauthenticate_params.rbi +1 -1
  75. data/rbi/lib/finch-api/models/hris/benefit_create_params.rbi +1 -1
  76. data/rbi/lib/finch-api/models/hris/benefit_list_params.rbi +1 -1
  77. data/rbi/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rbi +1 -1
  78. data/rbi/lib/finch-api/models/hris/benefit_retrieve_params.rbi +1 -1
  79. data/rbi/lib/finch-api/models/hris/benefit_update_params.rbi +1 -1
  80. data/rbi/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rbi +1 -1
  81. data/rbi/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbi +1 -1
  82. data/rbi/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbi +1 -1
  83. data/rbi/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rbi +1 -1
  84. data/rbi/lib/finch-api/models/hris/company_retrieve_params.rbi +1 -1
  85. data/rbi/lib/finch-api/models/hris/directory_list_individuals_params.rbi +1 -1
  86. data/rbi/lib/finch-api/models/hris/directory_list_params.rbi +1 -1
  87. data/rbi/lib/finch-api/models/hris/document_list_params.rbi +1 -1
  88. data/rbi/lib/finch-api/models/hris/document_retreive_params.rbi +1 -1
  89. data/rbi/lib/finch-api/models/hris/employment_retrieve_many_params.rbi +1 -1
  90. data/rbi/lib/finch-api/models/hris/individual_retrieve_many_params.rbi +1 -1
  91. data/rbi/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rbi +1 -1
  92. data/rbi/lib/finch-api/models/hris/payment_list_params.rbi +1 -1
  93. data/rbi/lib/finch-api/models/introspection.rbi +20 -3
  94. data/rbi/lib/finch-api/models/jobs/automated_create_params.rbi +1 -1
  95. data/rbi/lib/finch-api/models/jobs/automated_list_params.rbi +1 -1
  96. data/rbi/lib/finch-api/models/jobs/automated_retrieve_params.rbi +1 -1
  97. data/rbi/lib/finch-api/models/jobs/manual_retrieve_params.rbi +1 -1
  98. data/rbi/lib/finch-api/models/payroll/pay_group_list_params.rbi +1 -1
  99. data/rbi/lib/finch-api/models/payroll/pay_group_retrieve_params.rbi +1 -1
  100. data/rbi/lib/finch-api/models/provider_list_params.rbi +1 -1
  101. data/rbi/lib/finch-api/models/request_forwarding_forward_params.rbi +1 -1
  102. data/rbi/lib/finch-api/models/sandbox/company_update_params.rbi +1 -1
  103. data/rbi/lib/finch-api/models/sandbox/connection_create_params.rbi +1 -1
  104. data/rbi/lib/finch-api/models/sandbox/connections/account_create_params.rbi +1 -1
  105. data/rbi/lib/finch-api/models/sandbox/connections/account_update_params.rbi +1 -1
  106. data/rbi/lib/finch-api/models/sandbox/directory_create_params.rbi +1 -1
  107. data/rbi/lib/finch-api/models/sandbox/directory_create_response.rbi +1 -1
  108. data/rbi/lib/finch-api/models/sandbox/employment_update_params.rbi +1 -1
  109. data/rbi/lib/finch-api/models/sandbox/individual_update_params.rbi +1 -1
  110. data/rbi/lib/finch-api/models/sandbox/job_create_params.rbi +1 -1
  111. data/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbi +1 -1
  112. data/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_response.rbi +4 -1
  113. data/rbi/lib/finch-api/models/sandbox/jobs/configuration_update_params.rbi +1 -1
  114. data/rbi/lib/finch-api/models/sandbox/payment_create_params.rbi +1 -1
  115. data/rbi/lib/finch-api/page.rbi +1 -1
  116. data/rbi/lib/finch-api/request_options.rbi +0 -15
  117. data/rbi/lib/finch-api/responses_page.rbi +1 -1
  118. data/rbi/lib/finch-api/single_page.rbi +1 -1
  119. data/rbi/lib/finch-api/transport/base_client.rbi +204 -0
  120. data/rbi/lib/finch-api/transport/pooled_net_requester.rbi +64 -0
  121. data/rbi/lib/finch-api/type/array_of.rbi +82 -0
  122. data/rbi/lib/finch-api/type/base_model.rbi +191 -0
  123. data/rbi/lib/finch-api/type/base_page.rbi +38 -0
  124. data/rbi/lib/finch-api/type/boolean_model.rbi +41 -0
  125. data/rbi/lib/finch-api/type/converter.rbi +101 -0
  126. data/rbi/lib/finch-api/type/enum.rbi +58 -0
  127. data/rbi/lib/finch-api/type/hash_of.rbi +86 -0
  128. data/rbi/lib/finch-api/type/request_parameters.rbi +20 -0
  129. data/rbi/lib/finch-api/type/union.rbi +66 -0
  130. data/rbi/lib/finch-api/type/unknown.rbi +37 -0
  131. data/rbi/lib/finch-api/type.rbi +23 -0
  132. data/rbi/lib/finch-api/version.rbi +1 -1
  133. data/sig/finch-api/client.rbs +1 -1
  134. data/sig/finch-api/individuals_page.rbs +1 -1
  135. data/sig/finch-api/models/access_token_create_params.rbs +1 -1
  136. data/sig/finch-api/models/account_disconnect_params.rbs +1 -1
  137. data/sig/finch-api/models/account_introspect_params.rbs +1 -1
  138. data/sig/finch-api/models/connect/session_new_params.rbs +1 -1
  139. data/sig/finch-api/models/connect/session_reauthenticate_params.rbs +1 -1
  140. data/sig/finch-api/models/hris/benefit_create_params.rbs +1 -1
  141. data/sig/finch-api/models/hris/benefit_list_params.rbs +1 -1
  142. data/sig/finch-api/models/hris/benefit_list_supported_benefits_params.rbs +1 -1
  143. data/sig/finch-api/models/hris/benefit_retrieve_params.rbs +1 -1
  144. data/sig/finch-api/models/hris/benefit_update_params.rbs +1 -1
  145. data/sig/finch-api/models/hris/benefits/individual_enroll_many_params.rbs +1 -1
  146. data/sig/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbs +1 -1
  147. data/sig/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbs +1 -1
  148. data/sig/finch-api/models/hris/benefits/individual_unenroll_many_params.rbs +1 -1
  149. data/sig/finch-api/models/hris/company_retrieve_params.rbs +1 -1
  150. data/sig/finch-api/models/hris/directory_list_individuals_params.rbs +1 -1
  151. data/sig/finch-api/models/hris/directory_list_params.rbs +1 -1
  152. data/sig/finch-api/models/hris/document_list_params.rbs +1 -1
  153. data/sig/finch-api/models/hris/document_retreive_params.rbs +1 -1
  154. data/sig/finch-api/models/hris/employment_retrieve_many_params.rbs +1 -1
  155. data/sig/finch-api/models/hris/individual_retrieve_many_params.rbs +1 -1
  156. data/sig/finch-api/models/hris/pay_statement_retrieve_many_params.rbs +1 -1
  157. data/sig/finch-api/models/hris/payment_list_params.rbs +1 -1
  158. data/sig/finch-api/models/introspection.rbs +10 -1
  159. data/sig/finch-api/models/jobs/automated_create_params.rbs +1 -1
  160. data/sig/finch-api/models/jobs/automated_list_params.rbs +1 -1
  161. data/sig/finch-api/models/jobs/automated_retrieve_params.rbs +1 -1
  162. data/sig/finch-api/models/jobs/manual_retrieve_params.rbs +1 -1
  163. data/sig/finch-api/models/payroll/pay_group_list_params.rbs +1 -1
  164. data/sig/finch-api/models/payroll/pay_group_retrieve_params.rbs +1 -1
  165. data/sig/finch-api/models/provider_list_params.rbs +1 -1
  166. data/sig/finch-api/models/request_forwarding_forward_params.rbs +1 -1
  167. data/sig/finch-api/models/sandbox/company_update_params.rbs +1 -1
  168. data/sig/finch-api/models/sandbox/connection_create_params.rbs +1 -1
  169. data/sig/finch-api/models/sandbox/connections/account_create_params.rbs +1 -1
  170. data/sig/finch-api/models/sandbox/connections/account_update_params.rbs +1 -1
  171. data/sig/finch-api/models/sandbox/directory_create_params.rbs +1 -1
  172. data/sig/finch-api/models/sandbox/employment_update_params.rbs +1 -1
  173. data/sig/finch-api/models/sandbox/individual_update_params.rbs +1 -1
  174. data/sig/finch-api/models/sandbox/job_create_params.rbs +1 -1
  175. data/sig/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbs +1 -1
  176. data/sig/finch-api/models/sandbox/jobs/configuration_update_params.rbs +1 -1
  177. data/sig/finch-api/models/sandbox/payment_create_params.rbs +1 -1
  178. data/sig/finch-api/page.rbs +1 -1
  179. data/sig/finch-api/request_options.rbs +0 -10
  180. data/sig/finch-api/responses_page.rbs +1 -1
  181. data/sig/finch-api/single_page.rbs +1 -1
  182. data/sig/finch-api/transport/base_client.rbs +110 -0
  183. data/sig/finch-api/transport/pooled_net_requester.rbs +39 -0
  184. data/sig/finch-api/type/array_of.rbs +36 -0
  185. data/sig/finch-api/type/base_model.rbs +73 -0
  186. data/sig/finch-api/type/base_page.rbs +22 -0
  187. data/sig/finch-api/type/boolean_model.rbs +18 -0
  188. data/sig/finch-api/type/converter.rbs +36 -0
  189. data/sig/finch-api/type/enum.rbs +22 -0
  190. data/sig/finch-api/type/hash_of.rbs +36 -0
  191. data/sig/finch-api/type/request_parameters.rbs +13 -0
  192. data/sig/finch-api/type/union.rbs +37 -0
  193. data/sig/finch-api/type/unknown.rbs +18 -0
  194. data/sig/finch-api/type.rbs +22 -0
  195. data/sig/finch-api/version.rbs +1 -1
  196. metadata +41 -17
  197. data/lib/finch-api/base_client.rb +0 -457
  198. data/lib/finch-api/base_model.rb +0 -1226
  199. data/lib/finch-api/base_page.rb +0 -59
  200. data/lib/finch-api/extern.rb +0 -7
  201. data/lib/finch-api/pooled_net_requester.rb +0 -180
  202. data/rbi/lib/finch-api/base_client.rbi +0 -196
  203. data/rbi/lib/finch-api/base_model.rbi +0 -643
  204. data/rbi/lib/finch-api/base_page.rbi +0 -36
  205. data/rbi/lib/finch-api/extern.rbi +0 -7
  206. data/rbi/lib/finch-api/pooled_net_requester.rbi +0 -59
  207. data/sig/finch-api/base_client.rbs +0 -106
  208. data/sig/finch-api/base_model.rbs +0 -260
  209. data/sig/finch-api/base_page.rbs +0 -20
  210. data/sig/finch-api/extern.rbs +0 -4
  211. data/sig/finch-api/pooled_net_requester.rbs +0 -37
@@ -1,1226 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FinchAPI
4
- # @api private
5
- module Converter
6
- # rubocop:disable Lint/UnusedMethodArgument
7
-
8
- # @api private
9
- #
10
- # @param value [Object]
11
- #
12
- # @return [Object]
13
- def coerce(value) = value
14
-
15
- # @api private
16
- #
17
- # @param value [Object]
18
- #
19
- # @return [Object]
20
- def dump(value) = value
21
-
22
- # @api private
23
- #
24
- # @param value [Object]
25
- #
26
- # @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
27
- def try_strict_coerce(value) = (raise NotImplementedError)
28
-
29
- # rubocop:enable Lint/UnusedMethodArgument
30
-
31
- class << self
32
- # @api private
33
- #
34
- # @param spec [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] .
35
- #
36
- # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
37
- #
38
- # @option spec [Proc] :enum
39
- #
40
- # @option spec [Proc] :union
41
- #
42
- # @option spec [Boolean] :"nil?"
43
- #
44
- # @return [Proc]
45
- def type_info(spec)
46
- case spec
47
- in Hash
48
- type_info(spec.slice(:const, :enum, :union).first&.last)
49
- in Proc
50
- spec
51
- in FinchAPI::Converter | Module | Symbol
52
- -> { spec }
53
- in true | false
54
- -> { FinchAPI::BooleanModel }
55
- in NilClass | Integer | Float
56
- -> { spec.class }
57
- end
58
- end
59
-
60
- # @api private
61
- #
62
- # Based on `target`, transform `value` into `target`, to the extent possible:
63
- #
64
- # 1. if the given `value` conforms to `target` already, return the given `value`
65
- # 2. if it's possible and safe to convert the given `value` to `target`, then the
66
- # converted value
67
- # 3. otherwise, the given `value` unaltered
68
- #
69
- # @param target [FinchAPI::Converter, Class]
70
- # @param value [Object]
71
- #
72
- # @return [Object]
73
- def coerce(target, value)
74
- case target
75
- in FinchAPI::Converter
76
- target.coerce(value)
77
- in Symbol
78
- case value
79
- in Symbol | String if (val = value.to_sym) == target
80
- val
81
- else
82
- value
83
- end
84
- in Module
85
- case target
86
- in -> { _1 <= NilClass }
87
- nil
88
- in -> { _1 <= Integer }
89
- value.is_a?(Numeric) ? Integer(value) : value
90
- in -> { _1 <= Float }
91
- value.is_a?(Numeric) ? Float(value) : value
92
- in -> { _1 <= Symbol }
93
- value.is_a?(String) ? value.to_sym : value
94
- in -> { _1 <= String }
95
- value.is_a?(Symbol) ? value.to_s : value
96
- in -> { _1 <= Date || _1 <= Time }
97
- value.is_a?(String) ? target.parse(value) : value
98
- in -> { _1 <= IO }
99
- value.is_a?(String) ? StringIO.new(value) : value
100
- else
101
- value
102
- end
103
- end
104
- end
105
-
106
- # @api private
107
- #
108
- # @param target [FinchAPI::Converter, Class]
109
- # @param value [Object]
110
- #
111
- # @return [Object]
112
- def dump(target, value)
113
- case target
114
- in FinchAPI::Converter
115
- target.dump(value)
116
- else
117
- value
118
- end
119
- end
120
-
121
- # @api private
122
- #
123
- # The underlying algorithm for computing maximal compatibility is subject to
124
- # future improvements.
125
- #
126
- # Similar to `#.coerce`, used to determine the best union variant to decode into.
127
- #
128
- # 1. determine if strict-ish coercion is possible
129
- # 2. return either result of successful coercion or if loose coercion is possible
130
- # 3. return a score for recursively tallied count for fields that can be coerced
131
- #
132
- # @param target [FinchAPI::Converter, Class]
133
- # @param value [Object]
134
- #
135
- # @return [Object]
136
- def try_strict_coerce(target, value)
137
- case target
138
- in FinchAPI::Converter
139
- target.try_strict_coerce(value)
140
- in Symbol
141
- case value
142
- in Symbol | String if (val = value.to_sym) == target
143
- [true, val, 1]
144
- else
145
- [false, false, 0]
146
- end
147
- in Module
148
- case [target, value]
149
- in [-> { _1 <= NilClass }, _]
150
- [true, nil, value.nil? ? 1 : 0]
151
- in [-> { _1 <= Integer }, Numeric]
152
- [true, Integer(value), 1]
153
- in [-> { _1 <= Float }, Numeric]
154
- [true, Float(value), 1]
155
- in [-> { _1 <= Symbol }, String]
156
- [true, value.to_sym, 1]
157
- in [-> { _1 <= String }, Symbol]
158
- [true, value.to_s, 1]
159
- in [-> { _1 <= Date || _1 <= Time }, String]
160
- Kernel.then do
161
- [true, target.parse(value), 1]
162
- rescue ArgumentError
163
- [false, false, 0]
164
- end
165
- in [_, ^target]
166
- [true, value, 1]
167
- else
168
- [false, false, 0]
169
- end
170
- end
171
- end
172
- end
173
- end
174
-
175
- # @api private
176
- #
177
- # @abstract
178
- #
179
- # When we don't know what to expect for the value.
180
- class Unknown
181
- extend FinchAPI::Converter
182
-
183
- # rubocop:disable Lint/UnusedMethodArgument
184
-
185
- # @param other [Object]
186
- #
187
- # @return [Boolean]
188
- def self.===(other) = true
189
-
190
- # @param other [Object]
191
- #
192
- # @return [Boolean]
193
- def self.==(other) = other.is_a?(Class) && other <= FinchAPI::Unknown
194
-
195
- class << self
196
- # @!parse
197
- # # @api private
198
- # #
199
- # # @param value [Object]
200
- # #
201
- # # @return [Object]
202
- # def coerce(value) = super
203
-
204
- # @!parse
205
- # # @api private
206
- # #
207
- # # @param value [Object]
208
- # #
209
- # # @return [Object]
210
- # def dump(value) = super
211
-
212
- # @api private
213
- #
214
- # @param value [Object]
215
- #
216
- # @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
217
- def try_strict_coerce(value)
218
- # prevent unknown variant from being chosen during the first coercion pass
219
- [false, true, 0]
220
- end
221
- end
222
-
223
- # rubocop:enable Lint/UnusedMethodArgument
224
- end
225
-
226
- # @api private
227
- #
228
- # @abstract
229
- #
230
- # Ruby has no Boolean class; this is something for models to refer to.
231
- class BooleanModel
232
- extend FinchAPI::Converter
233
-
234
- # @param other [Object]
235
- #
236
- # @return [Boolean]
237
- def self.===(other) = other == true || other == false
238
-
239
- # @param other [Object]
240
- #
241
- # @return [Boolean]
242
- def self.==(other) = other.is_a?(Class) && other <= FinchAPI::BooleanModel
243
-
244
- class << self
245
- # @!parse
246
- # # @api private
247
- # #
248
- # # @param value [Boolean, Object]
249
- # #
250
- # # @return [Boolean, Object]
251
- # def coerce(value) = super
252
-
253
- # @!parse
254
- # # @api private
255
- # #
256
- # # @param value [Boolean, Object]
257
- # #
258
- # # @return [Boolean, Object]
259
- # def dump(value) = super
260
-
261
- # @api private
262
- #
263
- # @param value [Object]
264
- #
265
- # @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
266
- def try_strict_coerce(value)
267
- case value
268
- in true | false
269
- [true, value, 1]
270
- else
271
- [false, false, 0]
272
- end
273
- end
274
- end
275
- end
276
-
277
- # @api private
278
- #
279
- # A value from among a specified list of options. OpenAPI enum values map to Ruby
280
- # values in the SDK as follows:
281
- #
282
- # 1. boolean => true | false
283
- # 2. integer => Integer
284
- # 3. float => Float
285
- # 4. string => Symbol
286
- #
287
- # We can therefore convert string values to Symbols, but can't convert other
288
- # values safely.
289
- #
290
- # @example
291
- # # `connection_status_type` is a `FinchAPI::Models::ConnectionStatusType`
292
- # case connection_status_type
293
- # when FinchAPI::Models::ConnectionStatusType::PENDING
294
- # # ...
295
- # when FinchAPI::Models::ConnectionStatusType::PROCESSING
296
- # # ...
297
- # when FinchAPI::Models::ConnectionStatusType::CONNECTED
298
- # # ...
299
- # else
300
- # puts(connection_status_type)
301
- # end
302
- #
303
- # @example
304
- # case connection_status_type
305
- # in :pending
306
- # # ...
307
- # in :processing
308
- # # ...
309
- # in :connected
310
- # # ...
311
- # else
312
- # puts(connection_status_type)
313
- # end
314
- module Enum
315
- include FinchAPI::Converter
316
-
317
- # All of the valid Symbol values for this enum.
318
- #
319
- # @return [Array<NilClass, Boolean, Integer, Float, Symbol>]
320
- def values = (@values ||= constants.map { const_get(_1) })
321
-
322
- # @api private
323
- #
324
- # Guard against thread safety issues by instantiating `@values`.
325
- private def finalize! = values
326
-
327
- # @param other [Object]
328
- #
329
- # @return [Boolean]
330
- def ===(other) = values.include?(other)
331
-
332
- # @param other [Object]
333
- #
334
- # @return [Boolean]
335
- def ==(other)
336
- other.is_a?(Module) && other.singleton_class.ancestors.include?(FinchAPI::Enum) && other.values.to_set == values.to_set
337
- end
338
-
339
- # @api private
340
- #
341
- # @param value [String, Symbol, Object]
342
- #
343
- # @return [Symbol, Object]
344
- def coerce(value)
345
- case value
346
- in Symbol | String if values.include?(val = value.to_sym)
347
- val
348
- else
349
- value
350
- end
351
- end
352
-
353
- # @!parse
354
- # # @api private
355
- # #
356
- # # @param value [Symbol, Object]
357
- # #
358
- # # @return [Symbol, Object]
359
- # def dump(value) = super
360
-
361
- # @api private
362
- #
363
- # @param value [Object]
364
- #
365
- # @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
366
- def try_strict_coerce(value)
367
- return [true, value, 1] if values.include?(value)
368
-
369
- case value
370
- in Symbol | String if values.include?(val = value.to_sym)
371
- [true, val, 1]
372
- else
373
- case [value, values.first]
374
- in [true | false, true | false] | [Integer, Integer] | [Symbol | String, Symbol]
375
- [false, true, 0]
376
- else
377
- [false, false, 0]
378
- end
379
- end
380
- end
381
- end
382
-
383
- # @api private
384
- #
385
- # @example
386
- # # `document_retreive_response` is a `FinchAPI::Models::HRIS::DocumentRetreiveResponse`
387
- # case document_retreive_response
388
- # when FinchAPI::Models::HRIS::W42020
389
- # puts(document_retreive_response.data)
390
- # when FinchAPI::Models::HRIS::W42005
391
- # puts(document_retreive_response.type)
392
- # else
393
- # puts(document_retreive_response)
394
- # end
395
- #
396
- # @example
397
- # case document_retreive_response
398
- # in {type: :w4_2020, data: data, year: year}
399
- # puts(data)
400
- # in {type: :w4_2005, data: data, year: year}
401
- # puts(year)
402
- # else
403
- # puts(document_retreive_response)
404
- # end
405
- module Union
406
- include FinchAPI::Converter
407
-
408
- # @api private
409
- #
410
- # All of the specified variant info for this union.
411
- #
412
- # @return [Array<Array(Symbol, Proc)>]
413
- private def known_variants = (@known_variants ||= [])
414
-
415
- # @api private
416
- #
417
- # @return [Array<Array(Symbol, Object)>]
418
- protected def derefed_variants
419
- @known_variants.map { |key, variant_fn| [key, variant_fn.call] }
420
- end
421
-
422
- # All of the specified variants for this union.
423
- #
424
- # @return [Array<Object>]
425
- def variants
426
- derefed_variants.map(&:last)
427
- end
428
-
429
- # @api private
430
- #
431
- # @param property [Symbol]
432
- private def discriminator(property)
433
- case property
434
- in Symbol
435
- @discriminator = property
436
- end
437
- end
438
-
439
- # @api private
440
- #
441
- # @param key [Symbol, Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class]
442
- #
443
- # @param spec [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class] .
444
- #
445
- # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
446
- #
447
- # @option spec [Proc] :enum
448
- #
449
- # @option spec [Proc] :union
450
- #
451
- # @option spec [Boolean] :"nil?"
452
- private def variant(key, spec = nil)
453
- variant_info =
454
- case key
455
- in Symbol
456
- [key, FinchAPI::Converter.type_info(spec)]
457
- in Proc | FinchAPI::Converter | Module | Hash
458
- [nil, FinchAPI::Converter.type_info(key)]
459
- end
460
-
461
- known_variants << variant_info
462
- end
463
-
464
- # @api private
465
- #
466
- # @param value [Object]
467
- #
468
- # @return [FinchAPI::Converter, Class, nil]
469
- private def resolve_variant(value)
470
- case [@discriminator, value]
471
- in [_, FinchAPI::BaseModel]
472
- value.class
473
- in [Symbol, Hash]
474
- key =
475
- if value.key?(@discriminator)
476
- value.fetch(@discriminator)
477
- elsif value.key?((discriminator = @discriminator.to_s))
478
- value.fetch(discriminator)
479
- end
480
-
481
- key = key.to_sym if key.is_a?(String)
482
- _, resolved = known_variants.find { |k,| k == key }
483
- resolved.nil? ? FinchAPI::Unknown : resolved.call
484
- else
485
- nil
486
- end
487
- end
488
-
489
- # rubocop:disable Style/HashEachMethods
490
- # rubocop:disable Style/CaseEquality
491
-
492
- # @param other [Object]
493
- #
494
- # @return [Boolean]
495
- def ===(other)
496
- known_variants.any? do |_, variant_fn|
497
- variant_fn.call === other
498
- end
499
- end
500
-
501
- # @param other [Object]
502
- #
503
- # @return [Boolean]
504
- def ==(other)
505
- other.is_a?(Module) && other.singleton_class.ancestors.include?(FinchAPI::Union) && other.derefed_variants == derefed_variants
506
- end
507
-
508
- # @api private
509
- #
510
- # @param value [Object]
511
- #
512
- # @return [Object]
513
- def coerce(value)
514
- if (variant = resolve_variant(value))
515
- return FinchAPI::Converter.coerce(variant, value)
516
- end
517
-
518
- matches = []
519
-
520
- known_variants.each do |_, variant_fn|
521
- variant = variant_fn.call
522
-
523
- case FinchAPI::Converter.try_strict_coerce(variant, value)
524
- in [true, coerced, _]
525
- return coerced
526
- in [false, true, score]
527
- matches << [score, variant]
528
- in [false, false, _]
529
- nil
530
- end
531
- end
532
-
533
- _, variant = matches.sort! { _2.first <=> _1.first }.find { |score,| !score.zero? }
534
- variant.nil? ? value : FinchAPI::Converter.coerce(variant, value)
535
- end
536
-
537
- # @api private
538
- #
539
- # @param value [Object]
540
- #
541
- # @return [Object]
542
- def dump(value)
543
- if (variant = resolve_variant(value))
544
- return FinchAPI::Converter.dump(variant, value)
545
- end
546
-
547
- known_variants.each do |_, variant_fn|
548
- variant = variant_fn.call
549
- if variant === value
550
- return FinchAPI::Converter.dump(variant, value)
551
- end
552
- end
553
- value
554
- end
555
-
556
- # @api private
557
- #
558
- # @param value [Object]
559
- #
560
- # @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
561
- def try_strict_coerce(value)
562
- # TODO(ruby) this will result in super linear decoding behaviour for nested unions
563
- # follow up with a decoding context that captures current strictness levels
564
- if (variant = resolve_variant(value))
565
- return Converter.try_strict_coerce(variant, value)
566
- end
567
-
568
- coercible = false
569
- max_score = 0
570
-
571
- known_variants.each do |_, variant_fn|
572
- variant = variant_fn.call
573
-
574
- case FinchAPI::Converter.try_strict_coerce(variant, value)
575
- in [true, coerced, score]
576
- return [true, coerced, score]
577
- in [false, true, score]
578
- coercible = true
579
- max_score = [max_score, score].max
580
- in [false, false, _]
581
- nil
582
- end
583
- end
584
-
585
- [false, coercible, max_score]
586
- end
587
-
588
- # rubocop:enable Style/CaseEquality
589
- # rubocop:enable Style/HashEachMethods
590
- end
591
-
592
- # @api private
593
- #
594
- # @abstract
595
- #
596
- # Array of items of a given type.
597
- class ArrayOf
598
- include FinchAPI::Converter
599
-
600
- # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class]
601
- #
602
- # @param spec [Hash{Symbol=>Object}] .
603
- #
604
- # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
605
- #
606
- # @option spec [Proc] :enum
607
- #
608
- # @option spec [Proc] :union
609
- #
610
- # @option spec [Boolean] :"nil?"
611
- def self.[](type_info, spec = {}) = new(type_info, spec)
612
-
613
- # @param other [Object]
614
- #
615
- # @return [Boolean]
616
- def ===(other)
617
- type = item_type
618
- case other
619
- in Array
620
- # rubocop:disable Style/CaseEquality
621
- other.all? { type === _1 }
622
- # rubocop:enable Style/CaseEquality
623
- else
624
- false
625
- end
626
- end
627
-
628
- # @param other [Object]
629
- #
630
- # @return [Boolean]
631
- def ==(other) = other.is_a?(FinchAPI::ArrayOf) && other.item_type == item_type
632
-
633
- # @api private
634
- #
635
- # @param value [Enumerable, Object]
636
- #
637
- # @return [Array<Object>, Object]
638
- def coerce(value)
639
- type = item_type
640
- case value
641
- in Enumerable unless value.is_a?(Hash)
642
- value.map { FinchAPI::Converter.coerce(type, _1) }
643
- else
644
- value
645
- end
646
- end
647
-
648
- # @api private
649
- #
650
- # @param value [Enumerable, Object]
651
- #
652
- # @return [Array<Object>, Object]
653
- def dump(value)
654
- type = item_type
655
- case value
656
- in Enumerable unless value.is_a?(Hash)
657
- value.map { FinchAPI::Converter.dump(type, _1) }.to_a
658
- else
659
- value
660
- end
661
- end
662
-
663
- # @api private
664
- #
665
- # @param value [Object]
666
- #
667
- # @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
668
- def try_strict_coerce(value)
669
- case value
670
- in Array
671
- type = item_type
672
- great_success = true
673
- tally = 0
674
-
675
- mapped =
676
- value.map do |item|
677
- case FinchAPI::Converter.try_strict_coerce(type, item)
678
- in [true, coerced, score]
679
- tally += score
680
- coerced
681
- in [false, true, score]
682
- great_success = false
683
- tally += score
684
- item
685
- in [false, false, _]
686
- great_success &&= item.nil?
687
- item
688
- end
689
- end
690
-
691
- if great_success
692
- [true, mapped, tally]
693
- else
694
- [false, true, tally]
695
- end
696
- else
697
- [false, false, 0]
698
- end
699
- end
700
-
701
- # @api private
702
- #
703
- # @return [FinchAPI::Converter, Class]
704
- protected def item_type = @item_type_fn.call
705
-
706
- # @api private
707
- #
708
- # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class]
709
- #
710
- # @param spec [Hash{Symbol=>Object}] .
711
- #
712
- # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
713
- #
714
- # @option spec [Proc] :enum
715
- #
716
- # @option spec [Proc] :union
717
- #
718
- # @option spec [Boolean] :"nil?"
719
- def initialize(type_info, spec = {})
720
- @item_type_fn = FinchAPI::Converter.type_info(type_info || spec)
721
- end
722
- end
723
-
724
- # @api private
725
- #
726
- # @abstract
727
- #
728
- # Hash of items of a given type.
729
- class HashOf
730
- include FinchAPI::Converter
731
-
732
- # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class]
733
- #
734
- # @param spec [Hash{Symbol=>Object}] .
735
- #
736
- # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
737
- #
738
- # @option spec [Proc] :enum
739
- #
740
- # @option spec [Proc] :union
741
- #
742
- # @option spec [Boolean] :"nil?"
743
- def self.[](type_info, spec = {}) = new(type_info, spec)
744
-
745
- # @param other [Object]
746
- #
747
- # @return [Boolean]
748
- def ===(other)
749
- type = item_type
750
- case other
751
- in Hash
752
- other.all? do |key, val|
753
- case [key, val]
754
- in [Symbol | String, ^type]
755
- true
756
- else
757
- false
758
- end
759
- end
760
- else
761
- false
762
- end
763
- end
764
-
765
- # @param other [Object]
766
- #
767
- # @return [Boolean]
768
- def ==(other) = other.is_a?(FinchAPI::HashOf) && other.item_type == item_type
769
-
770
- # @api private
771
- #
772
- # @param value [Hash{Object=>Object}, Object]
773
- #
774
- # @return [Hash{Symbol=>Object}, Object]
775
- def coerce(value)
776
- type = item_type
777
- case value
778
- in Hash
779
- value.to_h do |key, val|
780
- coerced = FinchAPI::Converter.coerce(type, val)
781
- [key.is_a?(String) ? key.to_sym : key, coerced]
782
- end
783
- else
784
- value
785
- end
786
- end
787
-
788
- # @api private
789
- #
790
- # @param value [Hash{Object=>Object}, Object]
791
- #
792
- # @return [Hash{Symbol=>Object}, Object]
793
- def dump(value)
794
- type = item_type
795
- case value
796
- in Hash
797
- value.transform_values do |val|
798
- FinchAPI::Converter.dump(type, val)
799
- end
800
- else
801
- value
802
- end
803
- end
804
-
805
- # @api private
806
- #
807
- # @param value [Object]
808
- #
809
- # @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
810
- def try_strict_coerce(value)
811
- case value
812
- in Hash
813
- type = item_type
814
- great_success = true
815
- tally = 0
816
-
817
- mapped =
818
- value.transform_values do |val|
819
- case FinchAPI::Converter.try_strict_coerce(type, val)
820
- in [true, coerced, score]
821
- tally += score
822
- coerced
823
- in [false, true, score]
824
- great_success = false
825
- tally += score
826
- val
827
- in [false, false, _]
828
- great_success &&= val.nil?
829
- val
830
- end
831
- end
832
-
833
- if great_success
834
- [true, mapped, tally]
835
- else
836
- [false, true, tally]
837
- end
838
- else
839
- [false, false, 0]
840
- end
841
- end
842
-
843
- # @api private
844
- #
845
- # @return [FinchAPI::Converter, Class]
846
- protected def item_type = @item_type_fn.call
847
-
848
- # @api private
849
- #
850
- # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class]
851
- #
852
- # @param spec [Hash{Symbol=>Object}] .
853
- #
854
- # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
855
- #
856
- # @option spec [Proc] :enum
857
- #
858
- # @option spec [Proc] :union
859
- #
860
- # @option spec [Boolean] :"nil?"
861
- def initialize(type_info, spec = {})
862
- @item_type_fn = FinchAPI::Converter.type_info(type_info || spec)
863
- end
864
- end
865
-
866
- # @abstract
867
- #
868
- # @example
869
- # # `operation_support_matrix` is a `FinchAPI::Models::OperationSupportMatrix`
870
- # operation_support_matrix => {
871
- # create: create,
872
- # delete: delete,
873
- # read: read
874
- # }
875
- class BaseModel
876
- extend FinchAPI::Converter
877
-
878
- class << self
879
- # @api private
880
- #
881
- # Assumes superclass fields are totally defined before fields are accessed /
882
- # defined on subclasses.
883
- #
884
- # @return [Hash{Symbol=>Hash{Symbol=>Object}}]
885
- def known_fields
886
- @known_fields ||= (self < FinchAPI::BaseModel ? superclass.known_fields.dup : {})
887
- end
888
-
889
- # @api private
890
- #
891
- # @return [Hash{Symbol=>Symbol}]
892
- def reverse_map
893
- @reverse_map ||= (self < FinchAPI::BaseModel ? superclass.reverse_map.dup : {})
894
- end
895
-
896
- # @api private
897
- #
898
- # @return [Hash{Symbol=>Hash{Symbol=>Object}}]
899
- def fields
900
- known_fields.transform_values do |field|
901
- {**field.except(:type_fn), type: field.fetch(:type_fn).call}
902
- end
903
- end
904
-
905
- # @api private
906
- #
907
- # @return [Hash{Symbol=>Proc}]
908
- def defaults = (@defaults ||= {})
909
-
910
- # @api private
911
- #
912
- # @param name_sym [Symbol]
913
- #
914
- # @param required [Boolean]
915
- #
916
- # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class]
917
- #
918
- # @param spec [Hash{Symbol=>Object}] .
919
- #
920
- # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
921
- #
922
- # @option spec [Proc] :enum
923
- #
924
- # @option spec [Proc] :union
925
- #
926
- # @option spec [Boolean] :"nil?"
927
- private def add_field(name_sym, required:, type_info:, spec:)
928
- type_fn, info =
929
- case type_info
930
- in Proc | Module | FinchAPI::Converter
931
- [FinchAPI::Converter.type_info({**spec, union: type_info}), spec]
932
- in Hash
933
- [FinchAPI::Converter.type_info(type_info), type_info]
934
- end
935
-
936
- fallback = info[:const]
937
- defaults[name_sym] = fallback if required && !info[:nil?] && info.key?(:const)
938
-
939
- key = info[:api_name]&.tap { reverse_map[_1] = name_sym } || name_sym
940
- setter = "#{name_sym}="
941
-
942
- if known_fields.key?(name_sym)
943
- [name_sym, setter].each { undef_method(_1) }
944
- end
945
-
946
- known_fields[name_sym] = {mode: @mode, key: key, required: required, type_fn: type_fn}
947
-
948
- define_method(setter) do |val|
949
- @data[key] = val
950
- end
951
-
952
- define_method(name_sym) do
953
- field_type = type_fn.call
954
- value = @data.fetch(key) { self.class.defaults[key] }
955
- FinchAPI::Converter.coerce(field_type, value)
956
- rescue StandardError
957
- name = self.class.name.split("::").last
958
- raise FinchAPI::ConversionError.new(
959
- "Failed to parse #{name}.#{name_sym} as #{field_type.inspect}. " \
960
- "To get the unparsed API response, use #{name}[:#{key}]."
961
- )
962
- end
963
- end
964
-
965
- # @api private
966
- #
967
- # @param name_sym [Symbol]
968
- #
969
- # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class]
970
- #
971
- # @param spec [Hash{Symbol=>Object}] .
972
- #
973
- # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
974
- #
975
- # @option spec [Proc] :enum
976
- #
977
- # @option spec [Proc] :union
978
- #
979
- # @option spec [Boolean] :"nil?"
980
- def required(name_sym, type_info, spec = {})
981
- add_field(name_sym, required: true, type_info: type_info, spec: spec)
982
- end
983
-
984
- # @api private
985
- #
986
- # @param name_sym [Symbol]
987
- #
988
- # @param type_info [Hash{Symbol=>Object}, Proc, FinchAPI::Converter, Class]
989
- #
990
- # @param spec [Hash{Symbol=>Object}] .
991
- #
992
- # @option spec [NilClass, TrueClass, FalseClass, Integer, Float, Symbol] :const
993
- #
994
- # @option spec [Proc] :enum
995
- #
996
- # @option spec [Proc] :union
997
- #
998
- # @option spec [Boolean] :"nil?"
999
- def optional(name_sym, type_info, spec = {})
1000
- add_field(name_sym, required: false, type_info: type_info, spec: spec)
1001
- end
1002
-
1003
- # @api private
1004
- #
1005
- # `request_only` attributes not excluded from `.#coerce` when receiving responses
1006
- # even if well behaved servers should not send them
1007
- #
1008
- # @param blk [Proc]
1009
- private def request_only(&blk)
1010
- @mode = :dump
1011
- blk.call
1012
- ensure
1013
- @mode = nil
1014
- end
1015
-
1016
- # @api private
1017
- #
1018
- # `response_only` attributes are omitted from `.#dump` when making requests
1019
- #
1020
- # @param blk [Proc]
1021
- private def response_only(&blk)
1022
- @mode = :coerce
1023
- blk.call
1024
- ensure
1025
- @mode = nil
1026
- end
1027
- end
1028
-
1029
- # @param other [Object]
1030
- #
1031
- # @return [Boolean]
1032
- def ==(other)
1033
- case other
1034
- in FinchAPI::BaseModel
1035
- self.class.fields == other.class.fields && @data == other.to_h
1036
- else
1037
- false
1038
- end
1039
- end
1040
-
1041
- class << self
1042
- # @api private
1043
- #
1044
- # @param value [FinchAPI::BaseModel, Hash{Object=>Object}, Object]
1045
- #
1046
- # @return [FinchAPI::BaseModel, Object]
1047
- def coerce(value)
1048
- case FinchAPI::Util.coerce_hash(value)
1049
- in Hash => coerced
1050
- new(coerced)
1051
- else
1052
- value
1053
- end
1054
- end
1055
-
1056
- # @api private
1057
- #
1058
- # @param value [FinchAPI::BaseModel, Object]
1059
- #
1060
- # @return [Hash{Object=>Object}, Object]
1061
- def dump(value)
1062
- unless (coerced = FinchAPI::Util.coerce_hash(value)).is_a?(Hash)
1063
- return value
1064
- end
1065
-
1066
- values = coerced.filter_map do |key, val|
1067
- name = key.to_sym
1068
- case (field = known_fields[name])
1069
- in nil
1070
- [name, val]
1071
- else
1072
- mode, type_fn, api_name = field.fetch_values(:mode, :type_fn, :key)
1073
- case mode
1074
- in :coerce
1075
- next
1076
- else
1077
- target = type_fn.call
1078
- [api_name, FinchAPI::Converter.dump(target, val)]
1079
- end
1080
- end
1081
- end.to_h
1082
-
1083
- defaults.each do |key, val|
1084
- next if values.key?(key)
1085
-
1086
- values[key] = val
1087
- end
1088
-
1089
- values
1090
- end
1091
-
1092
- # @api private
1093
- #
1094
- # @param value [Object]
1095
- #
1096
- # @return [Array(true, Object, nil), Array(false, Boolean, Integer)]
1097
- def try_strict_coerce(value)
1098
- case value
1099
- in Hash | FinchAPI::BaseModel
1100
- value = value.to_h
1101
- else
1102
- return [false, false, 0]
1103
- end
1104
-
1105
- keys = value.keys.to_set
1106
- great_success = true
1107
- tally = 0
1108
- acc = {}
1109
-
1110
- known_fields.each_value do |field|
1111
- mode, required, type_fn, api_name = field.fetch_values(:mode, :required, :type_fn, :key)
1112
- keys.delete(api_name)
1113
-
1114
- case [required && mode != :dump, value.key?(api_name)]
1115
- in [_, true]
1116
- target = type_fn.call
1117
- item = value.fetch(api_name)
1118
- case FinchAPI::Converter.try_strict_coerce(target, item)
1119
- in [true, coerced, score]
1120
- tally += score
1121
- acc[api_name] = coerced
1122
- in [false, true, score]
1123
- great_success = false
1124
- tally += score
1125
- acc[api_name] = item
1126
- in [false, false, _]
1127
- great_success &&= item.nil?
1128
- end
1129
- in [true, false]
1130
- great_success = false
1131
- in [false, false]
1132
- nil
1133
- end
1134
- end
1135
-
1136
- keys.each do |key|
1137
- acc[key] = value.fetch(key)
1138
- end
1139
-
1140
- great_success ? [true, new(acc), tally] : [false, true, tally]
1141
- end
1142
- end
1143
-
1144
- # Returns the raw value associated with the given key, if found. Otherwise, nil is
1145
- # returned.
1146
- #
1147
- # It is valid to lookup keys that are not in the API spec, for example to access
1148
- # undocumented features. This method does not parse response data into
1149
- # higher-level types. Lookup by anything other than a Symbol is an ArgumentError.
1150
- #
1151
- # @param key [Symbol]
1152
- #
1153
- # @return [Object, nil]
1154
- def [](key)
1155
- unless key.instance_of?(Symbol)
1156
- raise ArgumentError.new("Expected symbol key for lookup, got #{key.inspect}")
1157
- end
1158
-
1159
- @data[key]
1160
- end
1161
-
1162
- # Returns a Hash of the data underlying this object. O(1)
1163
- #
1164
- # Keys are Symbols and values are the raw values from the response. The return
1165
- # value indicates which values were ever set on the object. i.e. there will be a
1166
- # key in this hash if they ever were, even if the set value was nil.
1167
- #
1168
- # This method is not recursive. The returned value is shared by the object, so it
1169
- # should not be mutated.
1170
- #
1171
- # @return [Hash{Symbol=>Object}]
1172
- def to_h = @data
1173
-
1174
- alias_method :to_hash, :to_h
1175
-
1176
- # @param keys [Array<Symbol>, nil]
1177
- #
1178
- # @return [Hash{Symbol=>Object}]
1179
- def deconstruct_keys(keys)
1180
- (keys || self.class.known_fields.keys).filter_map do |k|
1181
- unless self.class.known_fields.key?(k)
1182
- next
1183
- end
1184
-
1185
- [k, method(k).call]
1186
- end
1187
- .to_h
1188
- end
1189
-
1190
- # Create a new instance of a model.
1191
- #
1192
- # @param data [Hash{Symbol=>Object}, FinchAPI::BaseModel]
1193
- def initialize(data = {})
1194
- case FinchAPI::Util.coerce_hash(data)
1195
- in Hash => coerced
1196
- @data = coerced.to_h do |key, value|
1197
- name = key.to_sym
1198
- mapped = self.class.reverse_map.fetch(name, name)
1199
- type = self.class.fields[mapped]&.fetch(:type)
1200
- stored =
1201
- case [type, value]
1202
- in [Module, Hash] if type <= FinchAPI::BaseModel
1203
- type.new(value)
1204
- in [FinchAPI::ArrayOf, Array] | [FinchAPI::HashOf, Hash]
1205
- type.coerce(value)
1206
- else
1207
- value
1208
- end
1209
- [name, stored]
1210
- end
1211
- else
1212
- raise ArgumentError.new("Expected a #{Hash} or #{FinchAPI::BaseModel}, got #{data.inspect}")
1213
- end
1214
- end
1215
-
1216
- # @return [String]
1217
- def to_s = @data.to_s
1218
-
1219
- # @return [String]
1220
- def inspect
1221
- "#<#{self.class.name}:0x#{object_id.to_s(16)} #{deconstruct_keys(nil).map do |k, v|
1222
- "#{k}=#{v.inspect}"
1223
- end.join(' ')}>"
1224
- end
1225
- end
1226
- end