Skip to content
Merged
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
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
57 changes: 6 additions & 51 deletions src/GoodCode.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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
{
Expand All @@ -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;
Expand Down Expand Up @@ -96,59 +94,16 @@ 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<string,int> $setCodes key-value set code array
* @return GoodCode The method returns GoodCode instance with the SetCode array
*
* @example GoodCode::setCodeOf(['7369'=>4,'4235'=>6])
*/
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;
}
}
78 changes: 78 additions & 0 deletions src/ValueObjects/SetGood.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace Cable8mm\GoodCode\ValueObjects;

use Cable8mm\GoodCode\Enums\GoodCodeType;
use Cable8mm\GoodCode\GoodCode;
use InvalidArgumentException;

class SetGood
{
const DELIMITER = 'zz';

const DELIMITER_COUNT = 'x';

private array $goods;

private function __construct(private readonly string $code)
{
$this->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<string,string> $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;
}
}
1 change: 1 addition & 0 deletions tests/Enums/GoodCodeTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
31 changes: 31 additions & 0 deletions tests/ValueObjects/SetGoodTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Cable8mm\GoodCode\Tests\ValueObjects;

use Cable8mm\GoodCode\ValueObjects\SetGood;
use PHPUnit\Framework\TestCase;

class SetGoodTest extends TestCase
{
public function test_create_instance_with_string()
{
$setGood = SetGood::of('SET43x3zz253x3');

$this->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');
}
}