Skip to content

Commit 2de56d4

Browse files
authored
Merge pull request #79 from php-api-clients/introduce-fibers
Introduce fibers with proper type hints
2 parents c9e262a + 3c48a46 commit 2de56d4

File tree

4 files changed

+154
-7
lines changed

4 files changed

+154
-7
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
"react/http": "^1.8",
3333
"reactivex/rxphp": "^2.0",
3434
"api-clients/contracts": "dev-main",
35-
"eventsauce/object-hydrator": "^1.1"
35+
"eventsauce/object-hydrator": "^1.1",
36+
"react/async": "^4.0"
3637
},
3738
"autoload": {
3839
"psr-4": {

composer.lock

Lines changed: 79 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Generator/Client.php

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ public static function generate(string $namespace, array $clients, SchemaRegistr
115115
)
116116
);
117117

118+
$rawCallReturnTypes = [];
118119
$operationCalls = [];
119120
$callReturnTypes = [];
120121

@@ -129,10 +130,10 @@ public static function generate(string $namespace, array $clients, SchemaRegistr
129130
$fallbackName = 'Operation\\' . $operationGroup . '\\Response\\' . (new Convert(str_replace('/', '\\', $contentType) . '\\H' . $code ))->toPascal();
130131
$object = '\\' . $namespace . 'Schema\\' . $schemaRegistry->get($contentTypeSchema->schema, $fallbackName);
131132
$callReturnTypes[] = ($contentTypeSchema->schema->type === 'array' ? '\\' . Observable::class . '<' : '') . $object . ($contentTypeSchema->schema->type === 'array' ? '>' : '');
132-
$contentTypeCases[] = $returnType[] = $contentTypeSchema->schema->type === 'array' ? '\\' . Observable::class : $object;
133+
$rawCallReturnTypes[] = $contentTypeCases[] = $returnType[] = $contentTypeSchema->schema->type === 'array' ? '\\' . Observable::class : $object;
133134
}
134135
if (count($contentTypeCases) === 0) {
135-
$returnType[] = $callReturnTypes[] = 'int';
136+
$rawCallReturnTypes[] = $returnType[] = $callReturnTypes[] = 'int';
136137
}
137138
}
138139
$operationCalls[] = [
@@ -175,7 +176,7 @@ public static function generate(string $namespace, array $clients, SchemaRegistr
175176
}
176177

177178
$class->addStmt(
178-
$factory->method('call')->makePublic()->setReturnType(
179+
$factory->method('callAsync')->makePublic()->setReturnType(
179180
new Node\Name('\\' . PromiseInterface::class)
180181
)->setDocComment(
181182
new Doc(implode(PHP_EOL, [
@@ -340,6 +341,46 @@ public static function generate(string $namespace, array $clients, SchemaRegistr
340341
))
341342
);
342343

344+
$class->addStmt(
345+
$factory->method('call')->makePublic()->setDocComment(
346+
new Doc(implode(PHP_EOL, [
347+
'/**',
348+
' * @return ' . (function (array $operationCalls): string {
349+
$count = count($operationCalls);
350+
$lastItem = $count - 1;
351+
$left = '';
352+
$right = '';
353+
for ($i = 0; $i < $count; $i++) {
354+
if ($i !== $lastItem) {
355+
$left .= '($call is ' . $operationCalls[$i]['className'] . '::OPERATION_MATCH ? ' . implode('|', array_unique($operationCalls[$i]['returnType'])) . ' : ';
356+
} else {
357+
$left .= implode('|', array_unique($operationCalls[$i]['returnType']));
358+
}
359+
$right .= ')';
360+
}
361+
return $left . $right;
362+
})($operationCalls),
363+
' */',
364+
]))
365+
)->setReturnType(implode('|', array_unique($rawCallReturnTypes)))->addParam((new Param('call'))->setType('string'))->addParam((new Param('params'))->setType('array')->setDefault([]))->addStmt(new Node\Stmt\Return_(
366+
new Node\Expr\FuncCall(
367+
new Node\Name('\React\Async\await'),
368+
[
369+
new Node\Arg(
370+
new Node\Expr\MethodCall(
371+
new Node\Expr\Variable('this'),
372+
new Node\Name('callAsync'),
373+
[
374+
new Node\Arg(new Node\Expr\Variable('call')),
375+
new Node\Arg(new Node\Expr\Variable('params')),
376+
]
377+
)
378+
),
379+
],
380+
)
381+
))
382+
);
383+
343384
yield new File($namespace . '\\' . 'Client', $stmt->addStmt($class)->getNode());
344385
}
345386
}

src/Generator/ClientInterface.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public static function generate(string $namespace, array $clients, SchemaRegistr
3535
$stmt = $factory->namespace(rtrim($namespace, '\\'));
3636

3737
$class = $factory->interface('ClientInterface');
38+
$rawCallReturnTypes = [];
3839
$operationCalls = [];
3940
$callReturnTypes = [];
4041

@@ -49,10 +50,10 @@ public static function generate(string $namespace, array $clients, SchemaRegistr
4950
$fallbackName = 'Operation\\' . $operationGroup . '\\Response\\' . (new Convert(str_replace('/', '\\', $contentType) . '\\H' . $code ))->toPascal();
5051
$object = '\\' . $namespace . 'Schema\\' . $schemaRegistry->get($contentTypeSchema->schema, $fallbackName);
5152
$callReturnTypes[] = ($contentTypeSchema->schema->type === 'array' ? '\\' . Observable::class . '<' : '') . $object . ($contentTypeSchema->schema->type === 'array' ? '>' : '');
52-
$contentTypeCases[] = $returnType[] = $contentTypeSchema->schema->type === 'array' ? '\\' . Observable::class : $object;
53+
$rawCallReturnTypes[] = $contentTypeCases[] = $returnType[] = $contentTypeSchema->schema->type === 'array' ? '\\' . Observable::class : $object;
5354
}
5455
if (count($contentTypeCases) === 0) {
55-
$returnType[] = $callReturnTypes[] = 'int';
56+
$rawCallReturnTypes[] = $returnType[] = $callReturnTypes[] = 'int';
5657
}
5758
}
5859
$operationCalls[] = [
@@ -74,6 +75,32 @@ public static function generate(string $namespace, array $clients, SchemaRegistr
7475

7576
$class->addStmt(
7677
$factory->method('call')->makePublic()->setReturnType(
78+
new Node\Name(implode('|', array_unique($rawCallReturnTypes)))
79+
)->setDocComment(
80+
new Doc(implode(PHP_EOL, [
81+
'/**',
82+
' * @return ' . (function (array $operationCalls): string {
83+
$count = count($operationCalls);
84+
$lastItem = $count - 1;
85+
$left = '';
86+
$right = '';
87+
for ($i = 0; $i < $count; $i++) {
88+
if ($i !== $lastItem) {
89+
$left .= '($call is ' . $operationCalls[$i]['className'] . '::OPERATION_MATCH ? ' . implode('|', array_unique($operationCalls[$i]['returnType'])) . ' : ';
90+
} else {
91+
$left .= implode('|', array_unique($operationCalls[$i]['returnType']));
92+
}
93+
$right .= ')';
94+
}
95+
return $left . $right;
96+
})($operationCalls),
97+
' */',
98+
]))
99+
)->addParam((new Param('call'))->setType('string'))->addParam((new Param('params'))->setType('array')->setDefault([]))
100+
);
101+
102+
$class->addStmt(
103+
$factory->method('callAsync')->makePublic()->setReturnType(
77104
new Node\Name('\\' . PromiseInterface::class)
78105
)->setDocComment(
79106
new Doc(implode(PHP_EOL, [

0 commit comments

Comments
 (0)