diff --git a/README.md b/README.md index 1c9a9ae..7c8fac6 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,11 @@ We have provided the API Documentation on the web. For more information, please ## Features -- [x] General good code parser +- [x] Normal good code parser - [x] Gift good code parser - [x] Set good code parser - [x] Complex good code parser -- [x] Option Good code parser(No code, name matched by name) +- [x] Option Good code parser(No code, it matched by name) ## Install @@ -96,6 +96,16 @@ print GoodCode::of($optionCode, option: $optionName, callback: function ($key, $ ``` +Special value object - `SetGood` + +```php +print SetGood::of('SET43x3zz253x3')->goods(); +//=> ['43' => 3, '253' => 3] + +print SetGood::ofArray(['43' => 3, '253' => 3])->code(); +//=> SET43x3zz253x3 +``` + ## Formatting ```sh diff --git a/src/GoodCode.php b/src/GoodCode.php index 5fe7949..b0b5f12 100644 --- a/src/GoodCode.php +++ b/src/GoodCode.php @@ -4,17 +4,13 @@ use BadFunctionCallException; use Cable8mm\GoodCode\Enums\GoodCodeType; -use InvalidArgumentException; +use Cable8mm\GoodCode\ValueObjects\SetGood; /** * Make set code, option code and so on. */ class GoodCode { - const SET_CODE_DELIMITER = 'zz'; - - const SET_CODE_DELIMITER_COUNT = 'x'; - private GoodCodeType $type; public function __construct( @@ -44,6 +40,8 @@ public function type(): GoodCodeType * If the code is set code, it will be array of good values. * If the code is normal code, it will be good code string. * the code shouldn't be option, complex and gift code. + * + * @throws BadFunctionCallException */ public function value(): int|string|array { @@ -52,7 +50,7 @@ public function value(): int|string|array } if ($this->type == GoodCodeType::SET) { - return self::getSetCodes($this->code); + return SetGood::of($this->code)->goods(); } return $this->code; @@ -96,7 +94,7 @@ public static function of(string $code, ?string $option = null, ?callable $callb /** * Make SetCode from key-value set code array. * - * @param array $setCodes key-value set code array + * @param array $setCodes key-value set code array * @return GoodCode The method returns GoodCode instance with the SetCode array * * @example GoodCode::setCodeOf(['7369'=>4,'4235'=>6]) @@ -104,51 +102,8 @@ public static function of(string $code, ?string $option = null, ?callable $callb public static function setCodeOf(array $setCodes): GoodCode { return new GoodCode( - self::makeSetCode($setCodes), + SetGood::ofArray($setCodes)->code(), GoodCodeType::SET ); } - - /** - * Make SetCode from key-value set code array. - * - * @param array $setCodes key-value set code array - * @return string The method returns GoodCode instance with the SetCode string - * - * @example GoodCode::setCodeOf(['7369'=>4,'4235'=>6]) - */ - private static function makeSetCode(array $setCodes): string - { - return GoodCodeType::SET->prefix().implode(self::SET_CODE_DELIMITER, array_map(function ($v, $k) { - return $k.self::SET_CODE_DELIMITER_COUNT.$v; - }, $setCodes, array_keys($setCodes))); - } - - /** - * Find set-good code by parsing. A set of good code aka set-code is a combination of two more goods codes. - * - * @param string $setCode "set1232x3ZZ322ZZ4313x4" means "1232" x 3 + "322" x 4 + "4313" x 4. "1232", "322" and "4312" are good codes. - * @return array The method returns good code array - * - * @throws InvalidArgumentException - */ - public static function getSetCodes(string $setCode): array - { - $escape = preg_replace('/^'.GoodCodeType::SET->prefix().'/i', '', $setCode); - - $goodCodes = explode(self::SET_CODE_DELIMITER, $escape); - - $parsedCodes = []; - - foreach ($goodCodes as $code) { - if (preg_match('/'.self::SET_CODE_DELIMITER_COUNT.'/i', $code)) { - [$k, $v] = explode(self::SET_CODE_DELIMITER_COUNT, $code); - } else { - [$k, $v] = [$code, 1]; - } - $parsedCodes[$k] = $v; - } - - return $parsedCodes; - } } diff --git a/src/ValueObjects/SetGood.php b/src/ValueObjects/SetGood.php new file mode 100644 index 0000000..9edfd12 --- /dev/null +++ b/src/ValueObjects/SetGood.php @@ -0,0 +1,78 @@ +pipe(); + } + + /** + * Find set-good code by parsing. A set of good code aka set-code is a combination of two more goods codes. + * + * @param string $setCode "set1232x3ZZ322ZZ4313x4" means "1232" x 3 + "322" x 4 + "4313" x 4. "1232", "322" and "4312" are good codes. + * @return array The method returns good code array + */ + private function pipe(): void + { + $payload = preg_replace('/^'.GoodCodeType::SET->prefix().'/i', '', $this->code); + + foreach (explode(SetGood::DELIMITER, $payload) as $good) { + [$k, $v] = explode(SetGood::DELIMITER_COUNT, $good); + $this->goods[$k] = $v; + } + } + + public static function of(string $code): SetGood + { + if (! preg_match('/^'.GoodCodeType::SET->prefix().'/i', $code)) { + throw new InvalidArgumentException('It is not valid code'); + } + + return new self($code); + } + + /** + * Create SetGood instance from key-value set code array. + * + * @param array $setCodes key-value set code array + * @return SetGood The method returns SetGood instance with the SetCode string + * + * @example GoodCode::setCodeOf(['7369'=>4,'4235'=>6]) => SET7369x4zz42335x6 + */ + public static function ofArray(array $setCodes): SetGood + { + $code = GoodCodeType::SET->prefix().implode(SetGood::DELIMITER, array_map(function ($v, $k) { + return $k.SetGood::DELIMITER_COUNT.$v; + }, $setCodes, array_keys($setCodes))); + + return static::of($code); + } + + public function code(): string + { + return $this->code; + } + + public function goods(): array + { + return $this->goods; + } + + public function toString(): string + { + return $this->code; + } +} diff --git a/tests/Enums/GoodCodeTypeTest.php b/tests/Enums/GoodCodeTypeTest.php index 7edc798..6e7ac58 100644 --- a/tests/Enums/GoodCodeTypeTest.php +++ b/tests/Enums/GoodCodeTypeTest.php @@ -16,6 +16,7 @@ public function test_good_code_type_class() 'OPT10' => GoodCodeType::OPTION, 'COM10' => GoodCodeType::COMPLEX, 'GIF10' => GoodCodeType::GIFT, + 'SETPM195x5' => GoodCodeType::SET, ]; foreach ($goodCodes as $goodCode => $goodCodeType) { diff --git a/tests/ValueObjects/SetGoodTest.php b/tests/ValueObjects/SetGoodTest.php new file mode 100644 index 0000000..00f5cd6 --- /dev/null +++ b/tests/ValueObjects/SetGoodTest.php @@ -0,0 +1,31 @@ +assertEquals(['43' => 3, '253' => 3], $setGood->goods()); + } + + public function test_create_instance_with_array() + { + $setGood = SetGood::ofArray(['43' => 3, '253' => 3]); + + $this->assertEquals('SET43x3zz253x3', $setGood->code()); + } + + public function test_fire_exception() + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('It is not valid code'); + + SetGood::of('sdf23brew'); + } +}