1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* Copyright (c) Nate Brunette. |
4
|
|
|
* Distributed under the MIT License (http://opensource.org/licenses/MIT) |
5
|
|
|
*/ |
6
|
|
|
|
7
|
|
|
declare(strict_types=1); |
8
|
|
|
|
9
|
|
|
namespace Tebru\Retrofit\Internal\Converter; |
10
|
|
|
|
11
|
|
|
use LogicException; |
12
|
|
|
use Tebru\PhpType\TypeToken; |
13
|
|
|
use Tebru\Retrofit\ConverterFactory; |
14
|
|
|
use Tebru\Retrofit\RequestBodyConverter; |
15
|
|
|
use Tebru\Retrofit\ResponseBodyConverter; |
16
|
|
|
use Tebru\Retrofit\StringConverter; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Class ConverterProvider |
20
|
|
|
* |
21
|
|
|
* Returns a [@see ConverterFactory] that matches the provided type |
22
|
|
|
* |
23
|
|
|
* @author Nate Brunette <[email protected]> |
24
|
|
|
*/ |
25
|
|
|
final class ConverterProvider |
26
|
|
|
{ |
27
|
|
|
/** |
28
|
|
|
* A cache of [@see ResponseBodyConverter]'s |
29
|
|
|
* |
30
|
|
|
* @var ResponseBodyConverter[] |
31
|
|
|
*/ |
32
|
|
|
private $responseBodyConverters = []; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* A cache of [@see RequestBodyConverter]'s |
36
|
|
|
* |
37
|
|
|
* @var RequestBodyConverter[] |
38
|
|
|
*/ |
39
|
|
|
private $requestBodyConverters = []; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* A cache of [@see StringConverter]'s |
43
|
|
|
* |
44
|
|
|
* @var StringConverter[] |
45
|
|
|
*/ |
46
|
|
|
private $stringConverters = []; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* An array of [@see ConverterFactory]'s |
50
|
|
|
* |
51
|
|
|
* @var ConverterFactory[] |
52
|
|
|
*/ |
53
|
|
|
private $converterFactories; |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Constructor |
57
|
|
|
* |
58
|
|
|
* @param ConverterFactory[] $factories |
59
|
|
|
*/ |
60
|
|
|
public function __construct(array $factories) |
61
|
|
|
{ |
62
|
|
|
$this->converterFactories = array_values($factories); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* Get a response body converter for type |
67
|
|
|
* |
68
|
|
|
* @param TypeToken $type |
69
|
|
|
* @return ResponseBodyConverter |
70
|
|
|
* @throws LogicException |
71
|
|
|
*/ |
72
|
|
View Code Duplication |
public function getResponseBodyConverter(TypeToken $type): ResponseBodyConverter |
|
|
|
|
73
|
|
|
{ |
74
|
|
|
$key = (string)$type; |
75
|
|
|
if (isset($this->responseBodyConverters[$key])) { |
76
|
|
|
return $this->responseBodyConverters[$key]; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
foreach ($this->converterFactories as $converterFactory) { |
80
|
|
|
$converter = $converterFactory->responseBodyConverter($type); |
81
|
|
|
if ($converter === null) { |
82
|
|
|
continue; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
$this->responseBodyConverters[$key] = $converter; |
86
|
|
|
|
87
|
|
|
return $converter; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
throw new LogicException(sprintf( |
91
|
|
|
'Retrofit: Could not get response body converter for type %s', |
92
|
|
|
$type |
93
|
|
|
)); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Get a request body converter for type |
98
|
|
|
* |
99
|
|
|
* @param TypeToken $type |
100
|
|
|
* @return RequestBodyConverter |
101
|
|
|
* @throws \LogicException |
102
|
|
|
*/ |
103
|
|
View Code Duplication |
public function getRequestBodyConverter(TypeToken $type): RequestBodyConverter |
|
|
|
|
104
|
|
|
{ |
105
|
|
|
$key = (string)$type; |
106
|
|
|
if (isset($this->requestBodyConverters[$key])) { |
107
|
|
|
return $this->requestBodyConverters[$key]; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
foreach ($this->converterFactories as $converterFactory) { |
111
|
|
|
$converter = $converterFactory->requestBodyConverter($type); |
112
|
|
|
if ($converter === null) { |
113
|
|
|
continue; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
$this->requestBodyConverters[$key] = $converter; |
117
|
|
|
|
118
|
|
|
return $converter; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
throw new LogicException(sprintf( |
122
|
|
|
'Retrofit: Could not get request body converter for type %s', |
123
|
|
|
$type |
124
|
|
|
)); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* Get a string converter for type |
129
|
|
|
* |
130
|
|
|
* @param TypeToken $type |
131
|
|
|
* @return StringConverter |
132
|
|
|
* @throws \LogicException |
133
|
|
|
*/ |
134
|
|
View Code Duplication |
public function getStringConverter(TypeToken $type): StringConverter |
|
|
|
|
135
|
|
|
{ |
136
|
|
|
$key = (string)$type; |
137
|
|
|
if (isset($this->stringConverters[$key])) { |
138
|
|
|
return $this->stringConverters[$key]; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
foreach ($this->converterFactories as $converterFactory) { |
142
|
|
|
$converter = $converterFactory->stringConverter($type); |
143
|
|
|
if ($converter === null) { |
144
|
|
|
continue; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
$this->stringConverters[$key] = $converter; |
148
|
|
|
|
149
|
|
|
return $converter; |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
throw new LogicException(sprintf( |
153
|
|
|
'Retrofit: Could not get string converter for type %s', |
154
|
|
|
$type |
155
|
|
|
)); |
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.