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.
- checksums.yaml +4 -4
- data/README.md +2 -8
- data/lib/finch-api/client.rb +1 -1
- data/lib/finch-api/individuals_page.rb +4 -4
- data/lib/finch-api/models/access_token_create_params.rb +1 -1
- data/lib/finch-api/models/account_disconnect_params.rb +1 -1
- data/lib/finch-api/models/account_introspect_params.rb +1 -1
- data/lib/finch-api/models/connect/session_new_params.rb +1 -1
- data/lib/finch-api/models/connect/session_reauthenticate_params.rb +1 -1
- data/lib/finch-api/models/hris/benefit_create_params.rb +1 -1
- data/lib/finch-api/models/hris/benefit_list_params.rb +1 -1
- data/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rb +1 -1
- data/lib/finch-api/models/hris/benefit_retrieve_params.rb +1 -1
- data/lib/finch-api/models/hris/benefit_update_params.rb +1 -1
- data/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rb +1 -1
- data/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rb +1 -1
- data/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rb +1 -1
- data/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rb +1 -1
- data/lib/finch-api/models/hris/company_retrieve_params.rb +1 -1
- data/lib/finch-api/models/hris/directory_list_individuals_params.rb +1 -1
- data/lib/finch-api/models/hris/directory_list_params.rb +1 -1
- data/lib/finch-api/models/hris/document_list_params.rb +1 -1
- data/lib/finch-api/models/hris/document_retreive_params.rb +1 -1
- data/lib/finch-api/models/hris/employment_retrieve_many_params.rb +1 -1
- data/lib/finch-api/models/hris/individual_retrieve_many_params.rb +1 -1
- data/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rb +1 -1
- data/lib/finch-api/models/hris/payment_list_params.rb +1 -1
- data/lib/finch-api/models/jobs/automated_create_params.rb +1 -1
- data/lib/finch-api/models/jobs/automated_list_params.rb +1 -1
- data/lib/finch-api/models/jobs/automated_retrieve_params.rb +1 -1
- data/lib/finch-api/models/jobs/manual_retrieve_params.rb +1 -1
- data/lib/finch-api/models/payroll/pay_group_list_params.rb +1 -1
- data/lib/finch-api/models/payroll/pay_group_retrieve_params.rb +1 -1
- data/lib/finch-api/models/provider_list_params.rb +1 -1
- data/lib/finch-api/models/request_forwarding_forward_params.rb +1 -1
- data/lib/finch-api/models/sandbox/company_update_params.rb +1 -1
- data/lib/finch-api/models/sandbox/connection_create_params.rb +1 -1
- data/lib/finch-api/models/sandbox/connections/account_create_params.rb +1 -1
- data/lib/finch-api/models/sandbox/connections/account_update_params.rb +1 -1
- data/lib/finch-api/models/sandbox/directory_create_params.rb +1 -1
- data/lib/finch-api/models/sandbox/employment_update_params.rb +1 -1
- data/lib/finch-api/models/sandbox/individual_update_params.rb +1 -1
- data/lib/finch-api/models/sandbox/job_create_params.rb +1 -1
- data/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rb +1 -1
- data/lib/finch-api/models/sandbox/jobs/configuration_update_params.rb +1 -1
- data/lib/finch-api/models/sandbox/payment_create_params.rb +1 -1
- data/lib/finch-api/page.rb +4 -4
- data/lib/finch-api/request_options.rb +0 -33
- data/lib/finch-api/responses_page.rb +3 -3
- data/lib/finch-api/single_page.rb +3 -3
- data/lib/finch-api/transport/base_client.rb +459 -0
- data/lib/finch-api/transport/pooled_net_requester.rb +182 -0
- data/lib/finch-api/type/array_of.rb +110 -0
- data/lib/finch-api/type/base_model.rb +355 -0
- data/lib/finch-api/type/base_page.rb +61 -0
- data/lib/finch-api/type/boolean_model.rb +52 -0
- data/lib/finch-api/type/converter.rb +211 -0
- data/lib/finch-api/type/enum.rb +105 -0
- data/lib/finch-api/type/hash_of.rb +136 -0
- data/lib/finch-api/type/request_parameters.rb +38 -0
- data/lib/finch-api/type/union.rb +204 -0
- data/lib/finch-api/type/unknown.rb +56 -0
- data/lib/finch-api/type.rb +23 -0
- data/lib/finch-api/version.rb +1 -1
- data/lib/finch-api.rb +13 -4
- data/rbi/lib/finch-api/client.rbi +1 -1
- data/rbi/lib/finch-api/individuals_page.rbi +1 -1
- data/rbi/lib/finch-api/models/access_token_create_params.rbi +1 -1
- data/rbi/lib/finch-api/models/account_disconnect_params.rbi +1 -1
- data/rbi/lib/finch-api/models/account_introspect_params.rbi +1 -1
- data/rbi/lib/finch-api/models/connect/session_new_params.rbi +1 -1
- data/rbi/lib/finch-api/models/connect/session_reauthenticate_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/benefit_create_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/benefit_list_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/benefit_list_supported_benefits_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/benefit_retrieve_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/benefit_update_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/benefits/individual_enroll_many_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/benefits/individual_unenroll_many_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/company_retrieve_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/directory_list_individuals_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/directory_list_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/document_list_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/document_retreive_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/employment_retrieve_many_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/individual_retrieve_many_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/pay_statement_retrieve_many_params.rbi +1 -1
- data/rbi/lib/finch-api/models/hris/payment_list_params.rbi +1 -1
- data/rbi/lib/finch-api/models/jobs/automated_create_params.rbi +1 -1
- data/rbi/lib/finch-api/models/jobs/automated_list_params.rbi +1 -1
- data/rbi/lib/finch-api/models/jobs/automated_retrieve_params.rbi +1 -1
- data/rbi/lib/finch-api/models/jobs/manual_retrieve_params.rbi +1 -1
- data/rbi/lib/finch-api/models/payroll/pay_group_list_params.rbi +1 -1
- data/rbi/lib/finch-api/models/payroll/pay_group_retrieve_params.rbi +1 -1
- data/rbi/lib/finch-api/models/provider_list_params.rbi +1 -1
- data/rbi/lib/finch-api/models/request_forwarding_forward_params.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/company_update_params.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/connection_create_params.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/connections/account_create_params.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/connections/account_update_params.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/directory_create_params.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/directory_create_response.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/employment_update_params.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/individual_update_params.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/job_create_params.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/jobs/configuration_retrieve_response.rbi +4 -1
- data/rbi/lib/finch-api/models/sandbox/jobs/configuration_update_params.rbi +1 -1
- data/rbi/lib/finch-api/models/sandbox/payment_create_params.rbi +1 -1
- data/rbi/lib/finch-api/page.rbi +1 -1
- data/rbi/lib/finch-api/request_options.rbi +0 -15
- data/rbi/lib/finch-api/responses_page.rbi +1 -1
- data/rbi/lib/finch-api/single_page.rbi +1 -1
- data/rbi/lib/finch-api/transport/base_client.rbi +204 -0
- data/rbi/lib/finch-api/transport/pooled_net_requester.rbi +64 -0
- data/rbi/lib/finch-api/type/array_of.rbi +82 -0
- data/rbi/lib/finch-api/type/base_model.rbi +191 -0
- data/rbi/lib/finch-api/type/base_page.rbi +38 -0
- data/rbi/lib/finch-api/type/boolean_model.rbi +41 -0
- data/rbi/lib/finch-api/type/converter.rbi +101 -0
- data/rbi/lib/finch-api/type/enum.rbi +58 -0
- data/rbi/lib/finch-api/type/hash_of.rbi +86 -0
- data/rbi/lib/finch-api/type/request_parameters.rbi +20 -0
- data/rbi/lib/finch-api/type/union.rbi +66 -0
- data/rbi/lib/finch-api/type/unknown.rbi +37 -0
- data/rbi/lib/finch-api/type.rbi +23 -0
- data/rbi/lib/finch-api/version.rbi +1 -1
- data/sig/finch-api/client.rbs +1 -1
- data/sig/finch-api/individuals_page.rbs +1 -1
- data/sig/finch-api/models/access_token_create_params.rbs +1 -1
- data/sig/finch-api/models/account_disconnect_params.rbs +1 -1
- data/sig/finch-api/models/account_introspect_params.rbs +1 -1
- data/sig/finch-api/models/connect/session_new_params.rbs +1 -1
- data/sig/finch-api/models/connect/session_reauthenticate_params.rbs +1 -1
- data/sig/finch-api/models/hris/benefit_create_params.rbs +1 -1
- data/sig/finch-api/models/hris/benefit_list_params.rbs +1 -1
- data/sig/finch-api/models/hris/benefit_list_supported_benefits_params.rbs +1 -1
- data/sig/finch-api/models/hris/benefit_retrieve_params.rbs +1 -1
- data/sig/finch-api/models/hris/benefit_update_params.rbs +1 -1
- data/sig/finch-api/models/hris/benefits/individual_enroll_many_params.rbs +1 -1
- data/sig/finch-api/models/hris/benefits/individual_enrolled_ids_params.rbs +1 -1
- data/sig/finch-api/models/hris/benefits/individual_retrieve_many_benefits_params.rbs +1 -1
- data/sig/finch-api/models/hris/benefits/individual_unenroll_many_params.rbs +1 -1
- data/sig/finch-api/models/hris/company_retrieve_params.rbs +1 -1
- data/sig/finch-api/models/hris/directory_list_individuals_params.rbs +1 -1
- data/sig/finch-api/models/hris/directory_list_params.rbs +1 -1
- data/sig/finch-api/models/hris/document_list_params.rbs +1 -1
- data/sig/finch-api/models/hris/document_retreive_params.rbs +1 -1
- data/sig/finch-api/models/hris/employment_retrieve_many_params.rbs +1 -1
- data/sig/finch-api/models/hris/individual_retrieve_many_params.rbs +1 -1
- data/sig/finch-api/models/hris/pay_statement_retrieve_many_params.rbs +1 -1
- data/sig/finch-api/models/hris/payment_list_params.rbs +1 -1
- data/sig/finch-api/models/jobs/automated_create_params.rbs +1 -1
- data/sig/finch-api/models/jobs/automated_list_params.rbs +1 -1
- data/sig/finch-api/models/jobs/automated_retrieve_params.rbs +1 -1
- data/sig/finch-api/models/jobs/manual_retrieve_params.rbs +1 -1
- data/sig/finch-api/models/payroll/pay_group_list_params.rbs +1 -1
- data/sig/finch-api/models/payroll/pay_group_retrieve_params.rbs +1 -1
- data/sig/finch-api/models/provider_list_params.rbs +1 -1
- data/sig/finch-api/models/request_forwarding_forward_params.rbs +1 -1
- data/sig/finch-api/models/sandbox/company_update_params.rbs +1 -1
- data/sig/finch-api/models/sandbox/connection_create_params.rbs +1 -1
- data/sig/finch-api/models/sandbox/connections/account_create_params.rbs +1 -1
- data/sig/finch-api/models/sandbox/connections/account_update_params.rbs +1 -1
- data/sig/finch-api/models/sandbox/directory_create_params.rbs +1 -1
- data/sig/finch-api/models/sandbox/employment_update_params.rbs +1 -1
- data/sig/finch-api/models/sandbox/individual_update_params.rbs +1 -1
- data/sig/finch-api/models/sandbox/job_create_params.rbs +1 -1
- data/sig/finch-api/models/sandbox/jobs/configuration_retrieve_params.rbs +1 -1
- data/sig/finch-api/models/sandbox/jobs/configuration_update_params.rbs +1 -1
- data/sig/finch-api/models/sandbox/payment_create_params.rbs +1 -1
- data/sig/finch-api/page.rbs +1 -1
- data/sig/finch-api/request_options.rbs +0 -10
- data/sig/finch-api/responses_page.rbs +1 -1
- data/sig/finch-api/single_page.rbs +1 -1
- data/sig/finch-api/transport/base_client.rbs +110 -0
- data/sig/finch-api/transport/pooled_net_requester.rbs +39 -0
- data/sig/finch-api/type/array_of.rbs +36 -0
- data/sig/finch-api/type/base_model.rbs +73 -0
- data/sig/finch-api/type/base_page.rbs +22 -0
- data/sig/finch-api/type/boolean_model.rbs +18 -0
- data/sig/finch-api/type/converter.rbs +36 -0
- data/sig/finch-api/type/enum.rbs +22 -0
- data/sig/finch-api/type/hash_of.rbs +36 -0
- data/sig/finch-api/type/request_parameters.rbs +13 -0
- data/sig/finch-api/type/union.rbs +37 -0
- data/sig/finch-api/type/unknown.rbs +18 -0
- data/sig/finch-api/type.rbs +22 -0
- data/sig/finch-api/version.rbs +1 -1
- metadata +40 -13
- data/lib/finch-api/base_client.rb +0 -457
- data/lib/finch-api/base_model.rb +0 -1174
- data/lib/finch-api/base_page.rb +0 -59
- data/lib/finch-api/pooled_net_requester.rb +0 -180
- data/rbi/lib/finch-api/base_client.rbi +0 -196
- data/rbi/lib/finch-api/base_model.rbi +0 -609
- data/rbi/lib/finch-api/base_page.rbi +0 -36
- data/rbi/lib/finch-api/pooled_net_requester.rbi +0 -59
- data/sig/finch-api/base_client.rbs +0 -106
- data/sig/finch-api/base_model.rbs +0 -248
- data/sig/finch-api/base_page.rbs +0 -20
- data/sig/finch-api/pooled_net_requester.rbs +0 -37
data/lib/finch-api/base_model.rb
DELETED
@@ -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
|