Create initial structure and classes

This commit is contained in:
2017-03-08 11:37:15 +03:00
commit 4984f44d0a
8 changed files with 1587 additions and 0 deletions

119
src/Reason.php Normal file
View File

@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
namespace Anwinged\Reason;
class Reason
{
/**
* @var ReasonStatusInterface
*/
private $status;
/**
* @var string[]
*/
private $messages;
/**
* @param ReasonStatusInterface $status
* @param string[] $messages
*/
public function __construct(ReasonStatusInterface $status, array $messages)
{
$this->status = $status;
$this->messages = $messages;
}
/**
* Clones the reason.
*/
public function __clone()
{
$this->status = clone $this->status;
}
/**
* @return ReasonStatusInterface
*/
public function getStatus(): ReasonStatusInterface
{
return clone $this->status;
}
/**
* @return string[]
*/
public function getMessages(): array
{
return $this->messages;
}
/**
* Appends reason to current and returns new reason.
*
* Reason with highest weighs wins.
*
* If other reason has highest weight, then it will be returned without changes.
* If weights are equal, then messages will be merged. Otherwise,
* returns current reason.
*
* Don't change original objects.
*
* @param Reason $other
*
* @return self
*/
public function andX(Reason $other): self
{
if ($other->getStatus()->getWeight() > $this->status->getWeight()) {
return clone $other;
}
if ($other->getStatus()->getWeight() === $this->status->getWeight()) {
return $this->withMessages($other->getMessages());
}
return clone $this;
}
/**
* Join reason to current and return new reason.
*
* Reason with lowest weight wins.
*
* If other reason has lowest weight, then it will be returned without changes.
* If weights are equal, then messages will be merged. Otherwise,
* returns current reason.
*
* @param Reason $other
*
* @return self
*/
public function orX(Reason $other): self
{
if ($other->getStatus()->getWeight() < $this->status->getWeight()) {
return clone $other;
}
if ($other->getStatus()->getWeight() === $this->status->getWeight()) {
return $this->withMessages($other->getMessages());
}
return clone $this;
}
/**
* @param string[] $messages
*
* @return self
*/
private function withMessages(array $messages): self
{
$reason = clone $this;
$reason->messages = array_merge($reason->messages, $messages);
return $reason;
}
}

View File

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Anwinged\Reason;
interface ReasonStatusInterface
{
/**
* @return bool
*/
public function isSuccess(): bool;
/**
* @return bool
*/
public function isFail(): bool;
/**
* @return int
*/
public function getWeight(): int;
}

View File

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
namespace Anwinged\Reason\Status;
use Anwinged\Reason\ReasonStatusInterface;
class BooleanStatus implements ReasonStatusInterface
{
/**
* @var bool
*/
private $value;
/**
* @param bool $value
*/
public function __construct(bool $value)
{
$this->value = $value;
}
/**
* @return bool
*/
public function isSuccess(): bool
{
return $this->value;
}
/**
* @return bool
*/
public function isFail(): bool
{
return !$this->value;
}
/**
* @return int
*/
public function getWeight(): int
{
return $this->value ? 0 : 1;
}
}