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