feat: Constraint 시스템에 NoPaneltyKey 추가
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace sammo\Constraint;
|
namespace sammo\Constraint;
|
||||||
|
|
||||||
abstract class Constraint{
|
abstract class Constraint
|
||||||
private function __construct(){
|
{
|
||||||
|
private function __construct()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const REQ_GENERAL = 0x10;
|
const REQ_GENERAL = 0x10;
|
||||||
@@ -18,7 +20,8 @@ abstract class Constraint{
|
|||||||
const REQ_NUMERIC_ARG = self::REQ_ARG | 0x4000;
|
const REQ_NUMERIC_ARG = self::REQ_ARG | 0x4000;
|
||||||
const REQ_BOOLEAN_ARG = self::REQ_ARG | 0x8000;
|
const REQ_BOOLEAN_ARG = self::REQ_ARG | 0x8000;
|
||||||
const REQ_ARRAY_ARG = self::REQ_ARG | 0x10000;
|
const REQ_ARRAY_ARG = self::REQ_ARG | 0x10000;
|
||||||
|
const REQ_BACKED_ENUM_ARG = self::REQ_ARG | 0x20000;
|
||||||
|
|
||||||
const REQ_VALUES = 0;
|
const REQ_VALUES = 0;
|
||||||
|
|
||||||
protected $general = null;
|
protected $general = null;
|
||||||
@@ -37,182 +40,241 @@ abstract class Constraint{
|
|||||||
protected $tested = false;
|
protected $tested = false;
|
||||||
protected $reason = null;
|
protected $reason = null;
|
||||||
|
|
||||||
abstract public function test():bool;
|
abstract public function test(): bool;
|
||||||
|
|
||||||
|
|
||||||
static public function requiredValueType():int{
|
static public function requiredValueType(): int
|
||||||
|
{
|
||||||
return static::REQ_VALUES;
|
return static::REQ_VALUES;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setGeneral(array $general){
|
public function setGeneral(array $general)
|
||||||
|
{
|
||||||
$this->general = $general;
|
$this->general = $general;
|
||||||
$this->tested = false;
|
$this->tested = false;
|
||||||
$this->reason = null;
|
$this->reason = null;
|
||||||
}
|
}
|
||||||
public function setCity(array $city){
|
public function setCity(array $city)
|
||||||
|
{
|
||||||
$this->city = $city;
|
$this->city = $city;
|
||||||
$this->tested = false;
|
$this->tested = false;
|
||||||
$this->reason = null;
|
$this->reason = null;
|
||||||
}
|
}
|
||||||
public function setNation(array $nation){
|
public function setNation(array $nation)
|
||||||
|
{
|
||||||
$this->nation = $nation;
|
$this->nation = $nation;
|
||||||
$this->tested = false;
|
$this->tested = false;
|
||||||
$this->reason = null;
|
$this->reason = null;
|
||||||
}
|
}
|
||||||
public function setArg($arg){
|
public function setArg($arg)
|
||||||
|
{
|
||||||
$this->arg = $arg;
|
$this->arg = $arg;
|
||||||
$this->tested = false;
|
$this->tested = false;
|
||||||
$this->reason = null;
|
$this->reason = null;
|
||||||
}
|
}
|
||||||
public function setEnv($env){
|
public function setEnv($env)
|
||||||
|
{
|
||||||
$this->env = $env;
|
$this->env = $env;
|
||||||
$this->tested = false;
|
$this->tested = false;
|
||||||
$this->reason = null;
|
$this->reason = null;
|
||||||
}
|
}
|
||||||
public function setCmdArg($cmd_arg){
|
public function setCmdArg($cmd_arg)
|
||||||
|
{
|
||||||
$this->cmd_arg = $cmd_arg;
|
$this->cmd_arg = $cmd_arg;
|
||||||
$this->tested = false;
|
$this->tested = false;
|
||||||
$this->reason = null;
|
$this->reason = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setDestGeneral(array $general){
|
public function setDestGeneral(array $general)
|
||||||
|
{
|
||||||
$this->destGeneral = $general;
|
$this->destGeneral = $general;
|
||||||
$this->tested = false;
|
$this->tested = false;
|
||||||
$this->reason = null;
|
$this->reason = null;
|
||||||
}
|
}
|
||||||
public function setDestCity(array $city){
|
public function setDestCity(array $city)
|
||||||
|
{
|
||||||
$this->destCity = $city;
|
$this->destCity = $city;
|
||||||
$this->tested = false;
|
$this->tested = false;
|
||||||
$this->reason = null;
|
$this->reason = null;
|
||||||
}
|
}
|
||||||
public function setDestNation(array $nation){
|
public function setDestNation(array $nation)
|
||||||
|
{
|
||||||
$this->destNation = $nation;
|
$this->destNation = $nation;
|
||||||
$this->tested = false;
|
$this->tested = false;
|
||||||
$this->reason = null;
|
$this->reason = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function build(array $input):self{
|
static public function build(array $input): self
|
||||||
|
{
|
||||||
$self = new static();
|
$self = new static();
|
||||||
foreach($input as $key=>$value){
|
foreach ($input as $key => $value) {
|
||||||
if($value === null){
|
if ($value === null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch($key){
|
switch ($key) {
|
||||||
case 'general': $self->setGeneral($value); break;
|
case 'general':
|
||||||
case 'city': $self->setCity($value); break;
|
$self->setGeneral($value);
|
||||||
case 'nation': $self->setNation($value); break;
|
break;
|
||||||
case 'cmd_arg': $self->setCmdArg($value); break;
|
case 'city':
|
||||||
|
$self->setCity($value);
|
||||||
|
break;
|
||||||
|
case 'nation':
|
||||||
|
$self->setNation($value);
|
||||||
|
break;
|
||||||
|
case 'cmd_arg':
|
||||||
|
$self->setCmdArg($value);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'destGeneral': $self->setDestGeneral($value); break;
|
case 'destGeneral':
|
||||||
case 'destCity': $self->setDestCity($value); break;
|
$self->setDestGeneral($value);
|
||||||
case 'destNation': $self->setDestNation($value); break;
|
break;
|
||||||
|
case 'destCity':
|
||||||
|
$self->setDestCity($value);
|
||||||
|
break;
|
||||||
|
case 'destNation':
|
||||||
|
$self->setDestNation($value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkInputValues(bool $throwExeception=true):bool{
|
public function checkInputValues(bool $throwExeception = true): bool
|
||||||
|
{
|
||||||
$valueType = static::requiredValueType();
|
$valueType = static::requiredValueType();
|
||||||
|
|
||||||
if(($valueType&static::REQ_GENERAL) && $this->general === null){
|
if (($valueType & static::REQ_GENERAL) && $this->general === null) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require general');
|
throw new \InvalidArgumentException('require general');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($valueType&static::REQ_CITY) && $this->city === null){
|
if (($valueType & static::REQ_CITY) && $this->city === null) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require city');
|
throw new \InvalidArgumentException('require city');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($valueType&static::REQ_NATION) && $this->nation === null){
|
if (($valueType & static::REQ_NATION) && $this->nation === null) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require nation');
|
throw new \InvalidArgumentException('require nation');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($valueType&static::REQ_DEST_GENERAL) && $this->destGeneral === null){
|
if (($valueType & static::REQ_DEST_GENERAL) && $this->destGeneral === null) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require dest general');
|
throw new \InvalidArgumentException('require dest general');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($valueType&static::REQ_DEST_CITY) && $this->destCity === null){
|
if (($valueType & static::REQ_DEST_CITY) && $this->destCity === null) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require dest city');
|
throw new \InvalidArgumentException('require dest city');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(($valueType&static::REQ_DEST_NATION) && $this->destNation === null){
|
if (($valueType & static::REQ_DEST_NATION) && $this->destNation === null) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require dest nation');
|
throw new \InvalidArgumentException('require dest nation');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!($valueType&static::REQ_ARG)) {
|
if (!($valueType & static::REQ_ARG)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($valueType === null){
|
if ($valueType === null) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require arg');
|
throw new \InvalidArgumentException('require arg');
|
||||||
}
|
}
|
||||||
|
|
||||||
if((($valueType&static::REQ_STRING_ARG)===static::REQ_STRING_ARG) && !is_string($this->arg)){
|
if ((($valueType & static::REQ_STRING_ARG) === static::REQ_STRING_ARG) && !is_string($this->arg)) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require string arg');
|
throw new \InvalidArgumentException('require string arg');
|
||||||
}
|
}
|
||||||
|
|
||||||
if((($valueType&static::REQ_BOOLEAN_ARG)===static::REQ_BOOLEAN_ARG) && !is_bool($this->arg)){
|
if ((($valueType & static::REQ_BOOLEAN_ARG) === static::REQ_BOOLEAN_ARG) && !is_bool($this->arg)) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require bool arg');
|
throw new \InvalidArgumentException('require bool arg');
|
||||||
}
|
}
|
||||||
|
|
||||||
if((($valueType&static::REQ_INT_ARG)===static::REQ_INT_ARG) && !is_int($this->arg)){
|
if ((($valueType & static::REQ_INT_ARG) === static::REQ_INT_ARG) && !is_int($this->arg)) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require int arg');
|
throw new \InvalidArgumentException('require int arg');
|
||||||
}
|
}
|
||||||
|
|
||||||
if((($valueType&static::REQ_NUMERIC_ARG)===static::REQ_NUMERIC_ARG) && !is_numeric($this->arg)){
|
if ((($valueType & static::REQ_NUMERIC_ARG) === static::REQ_NUMERIC_ARG) && !is_numeric($this->arg)) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require numeric arg');
|
throw new \InvalidArgumentException('require numeric arg');
|
||||||
}
|
}
|
||||||
|
|
||||||
if((($valueType&static::REQ_ARRAY_ARG)===static::REQ_ARRAY_ARG) && !is_array($this->arg)){
|
if ((($valueType & static::REQ_ARRAY_ARG) === static::REQ_ARRAY_ARG) && !is_array($this->arg)) {
|
||||||
if(!$throwExeception){return false; }
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
throw new \InvalidArgumentException('require array arg');
|
throw new \InvalidArgumentException('require array arg');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((($valueType & static::REQ_BACKED_ENUM_ARG) === static::REQ_BACKED_ENUM_ARG) && !($this->arg instanceof \BackedEnum)) {
|
||||||
|
if (!$throwExeception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
throw new \InvalidArgumentException('require backed enum arg');
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reason():?string{
|
public function reason(): ?string
|
||||||
if($this->tested === false){
|
{
|
||||||
throw new \RuntimeException(get_class($this).'::test가 실행되지 않음');
|
if ($this->tested === false) {
|
||||||
|
throw new \RuntimeException(get_class($this) . '::test가 실행되지 않음');
|
||||||
}
|
}
|
||||||
return $this->reason;
|
return $this->reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function testAll(array $constraintPacks, array $input, array $env):?array{
|
public static function testAll(array $constraintPacks, array $input, array $env): ?array
|
||||||
foreach($constraintPacks as $constraintArgs){
|
{
|
||||||
if (!$constraintArgs){
|
foreach ($constraintPacks as $constraintArgs) {
|
||||||
|
if (!$constraintArgs) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$constraintName = $constraintArgs[0];
|
$constraintName = $constraintArgs[0];
|
||||||
$method = __NAMESPACE__.'\\'.$constraintName.'::build';
|
$method = __NAMESPACE__ . '\\' . $constraintName . '::build';
|
||||||
|
|
||||||
/** @var \sammo\Constraint\Constraint $contraint */
|
/** @var \sammo\Constraint\Constraint $contraint */
|
||||||
$constraint = call_user_func($method,$input);
|
$constraint = call_user_func($method, $input);
|
||||||
|
|
||||||
assert($constraint instanceof Constraint);
|
assert($constraint instanceof Constraint);
|
||||||
$constraint->setEnv($env);
|
$constraint->setEnv($env);
|
||||||
if(count($constraintArgs) == 2){
|
if (count($constraintArgs) == 2) {
|
||||||
$arg = $constraintArgs[1];
|
$arg = $constraintArgs[1];
|
||||||
$constraint->setArg($arg);
|
$constraint->setArg($arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(!$constraint->test()){
|
|
||||||
|
|
||||||
if($constraint->reason() === null){
|
if (!$constraint->test()) {
|
||||||
throw new \RuntimeException('Reason is not set:'.$constraintName);
|
|
||||||
|
if ($constraint->reason() === null) {
|
||||||
|
throw new \RuntimeException('Reason is not set:' . $constraintName);
|
||||||
}
|
}
|
||||||
return [$constraintName, $constraint->reason()];
|
return [$constraintName, $constraint->reason()];
|
||||||
}
|
}
|
||||||
@@ -220,5 +282,4 @@ abstract class Constraint{
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace sammo\Constraint;
|
namespace sammo\Constraint;
|
||||||
|
|
||||||
|
use sammo\Enums\PenaltyKey;
|
||||||
|
|
||||||
class ConstraintHelper{
|
class ConstraintHelper{
|
||||||
|
|
||||||
static function AdhocCallback(callable $callback):array{
|
static function AdhocCallback(callable $callback):array{
|
||||||
@@ -176,6 +178,10 @@ class ConstraintHelper{
|
|||||||
return [__FUNCTION__];
|
return [__FUNCTION__];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function NoPanelty(PenaltyKey $penaltyKey):array{
|
||||||
|
return [__FUNCTION__, $penaltyKey];
|
||||||
|
}
|
||||||
|
|
||||||
static function OccupiedCity(bool $allowNeutral=false):array{
|
static function OccupiedCity(bool $allowNeutral=false):array{
|
||||||
return [__FUNCTION__, $allowNeutral];
|
return [__FUNCTION__, $allowNeutral];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\Constraint;
|
||||||
|
|
||||||
|
use sammo\Enums\PenaltyKey;
|
||||||
|
use sammo\Json;
|
||||||
|
|
||||||
|
class NoPanelty extends Constraint{
|
||||||
|
const REQ_VALUES = Constraint::REQ_GENERAL|Constraint::REQ_ARG|Constraint::REQ_BACKED_ENUM_ARG;
|
||||||
|
|
||||||
|
public function checkInputValues(bool $throwExeception=true):bool{
|
||||||
|
if(!parent::checkInputValues($throwExeception) && !$throwExeception){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!key_exists('penalty', $this->general)){
|
||||||
|
if(!$throwExeception){return false; }
|
||||||
|
throw new \InvalidArgumentException("require penalty in general");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!($this->arg instanceof PenaltyKey)){
|
||||||
|
if(!$throwExeception){return false; }
|
||||||
|
throw new \InvalidArgumentException("require penalty key");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test():bool{
|
||||||
|
$this->checkInputValues();
|
||||||
|
$this->tested = true;
|
||||||
|
|
||||||
|
/** @var PenaltyKey */
|
||||||
|
$checkKey = $this->arg;
|
||||||
|
|
||||||
|
$peneltyList = JSON::decode($this->general['penalty']);
|
||||||
|
if(!key_exists($checkKey->value, $peneltyList)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->reason = "징계 사유: {$peneltyList[$checkKey->value]}";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user