Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] Pipeline function control #198

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"src/System/Collection/helper.php",
"src/System/Integrate/helper.php",
"src/System/Console/helper.php",
"src/System/Support/helper.php",
"src/System/Text/helper.php",
"src/System/Time/helper.php"
]
Expand Down
181 changes: 181 additions & 0 deletions src/System/Support/Pipeline/Action.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
<?php

declare(strict_types=1);

namespace System\Support\Pipeline;

use System\Collection\Collection;

/**
* @template T
*/
final class Action
{
/**
* Callback prepare collection.
*
* @var Collection<int, callable>
*/
private Collection $prepares;

/**
* Main function to call.
*
* @template T
*
* @var callable(T): T
*/
private $main;

/**
* Result of main callback.
*
* @var T
*/
private $result;

/**
* Exception from mainfunction.
*
* @var \Throwable|null
*/
private $throw;

/**
* Catch function, call if throw have error.
*
* @var callable(\Throwable)
*/
private $catch;

/**
* Retry atempts.
*/
private int $retry;

/**
* Paremeter for set in main function.
*
* @var array<string, mixed>
*/
private $parameters;

/**
* @param Collection<int, callable> $prepares
* @param callable(T): T $main
* @param array<string, mixed> $parameters
*/
public function __construct($prepares, $main, $parameters)
{
$this->prepares = $prepares;
$this->main = $main;
$this->result = null;
$this->throw = null;
$this->catch = function ($throw) {};
$this->retry = 1;
$this->parameters = $parameters;
}

private function do(): void
{
$atempt = $this->retry;
while ($atempt > 0) {
try {
$this->result = call_user_func_array($this->main, $this->parameters);
$atempt = 0;
} catch (\Throwable $th) {
$atempt--;
$this->throw = $th;
}
}
if (null !== $this->throw) {
($this->catch)($this->throw);
}
}

/**
* Set attempt to re run main code.
*
* @return $this
*/
public function retry(int $retry): self
{
$this->retry = $retry;

return $this;
}

/**
* Catch throable if mainc code get error.
*
* @param callable(\Throwable): void $callback
*
* @return $this
*/
public function catch($callback): self
{
$this->catch = $callback;

return $this;
}

/**
* Last action of pipeline.
*
* @param callable(T): void $callback
*
* @return $this
*/
public function success($callback): self
{
$this->prepares->each(function ($prepare) {
($prepare)();

return true;
});
$this->do();
if (null === $this->throw) {
($callback)($this->result);
}

return $this;
}

/**
* Final of Pipeline action.
*
* @param callable(): void $callback
*/
public function finally($callback): void
{
if (null === $this->result && null === $this->throw) {
$this->success(function () {});
}
($callback)();
}

/**
* Contionue call other action if success.
*
* @param callable(T): T $callback
*
* @return Action<T>
*/
public function then($callback): Action
{
$this->success(function () {});
$pipe = new Pipeline();
$pipe->with([
'result' => $this->result,
]);

$next = null === $this->throw
? $callback
: fn ($result) => null;

$action = $pipe->through(fn ($result) => ($next)($result));
$action->throw = $this->throw;

return $action;
}
}
71 changes: 71 additions & 0 deletions src/System/Support/Pipeline/Pipeline.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

namespace System\Support\Pipeline;

use System\Collection\Collection;

/**
* Pipeline.
*/
final class Pipeline
{
/**
* Callback prepare collection.
*
* @var Collection<int,callable>
*/
private $prepares;

/**
* Parameters.
*
* @var array<string,>
*/
private $parameters;

public function __construct()
{
$this->prepares = new Collection([]);
$this->parameters = [];
}

/**
* Prepare function.
*
* @param callable $callback
*/
public function prepare($callback): self
{
$i = $this->prepares->lastKey();
$i++;
$this->prepares->set($i, $callback);
Comment on lines +41 to +43
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use new collection push method


return $this;
}

/**
* Set parameters.
*
* @param array<string, mixed> $parameters
*/
public function with($parameters): self
{
$this->parameters = $parameters;

return $this;
}

/**
* @template T
*
* @param callable(T): T $callback
*
* @return Action<T>
*/
public function through($callback): Action
{
return new Action($this->prepares, $callback, $this->parameters);
}
}
22 changes: 22 additions & 0 deletions src/System/Support/helper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

use System\Support\Pipeline\Pipeline;

if (!function_exists('pipe')) {
/**
* Create pipeline funtion.
*
* @param callable $prepare
**/
function pipe($prepare = null): Pipeline
{
$pipe = new Pipeline();
if (null !== $prepare) {
$pipe->prepare($prepare);
}

return $pipe;
}
}
Loading