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
18 changes: 18 additions & 0 deletions src/Integer/Alias/TinyInt.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace PhpTypedValues\Integer\Alias;

use PhpTypedValues\Integer\DB\IntTiny;

/**
* Alias of IntTiny.
*
* Example "1"
*
* @psalm-immutable
*/
readonly class TinyInt extends IntTiny
{
}
61 changes: 61 additions & 0 deletions src/Integer/DB/IntTiny.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

namespace PhpTypedValues\Integer\DB;

use PhpTypedValues\Abstract\Integer\IntType;
use PhpTypedValues\Exception\IntegerTypeException;

use function sprintf;

/**
* Database tiny integer (TINYINT signed: -128..127).
*
* Example "-5"
*
* @psalm-immutable
*/
readonly class IntTiny extends IntType
{
/** @var int<-128, 127> */
protected int $value;

/**
* @throws IntegerTypeException
*/
public function __construct(int $value)
{
if ($value < -128 || $value > 127) {
throw new IntegerTypeException(sprintf('Expected tiny integer in range -128..127, got "%d"', $value));
}

$this->value = $value;
}

/**
* @throws IntegerTypeException
*/
public static function fromInt(int $value): static
{
return new static($value);
}

/**
* @throws IntegerTypeException
*/
public static function fromString(string $value): static
{
parent::assertIntegerString($value);

return new static((int) $value);
}

/**
* @return int<-128, 127>
*/
public function value(): int
{
return $this->value;
}
}
7 changes: 7 additions & 0 deletions src/psalmTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
use PhpTypedValues\Integer\Alias\IntType;
use PhpTypedValues\Integer\Alias\NonNegativeInt;
use PhpTypedValues\Integer\Alias\PositiveInt;
use PhpTypedValues\Integer\Alias\TinyInt;
use PhpTypedValues\Integer\DB\IntTiny;
use PhpTypedValues\Integer\IntegerNonNegative;
use PhpTypedValues\Integer\IntegerPositive;
use PhpTypedValues\Integer\IntegerStandard;
Expand All @@ -37,6 +39,11 @@
testNonNegativeInt(IntegerNonNegative::fromInt(10)->value());
testWeekDayInt(IntegerWeekDay::fromInt(7)->value());

// DB tinyint usage
echo TinyInt::fromInt(-5)->toString() . \PHP_EOL;
echo IntTiny::fromInt(-5)->toString() . \PHP_EOL;
echo IntTiny::fromString('127')->toString() . \PHP_EOL;

echo NonNegativeInt::fromString('10')->toString() . \PHP_EOL;
echo PositiveInt::fromString('10')->toString() . \PHP_EOL;
echo IntegerStandard::fromString('10')->toString() . \PHP_EOL;
Expand Down
40 changes: 40 additions & 0 deletions tests/Unit/Integer/DB/IntTinyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

use PhpTypedValues\Exception\IntegerTypeException;
use PhpTypedValues\Integer\DB\IntTiny;

it('accepts values within signed tinyint range and preserves value', function (): void {
$a = new IntTiny(-128);
$b = IntTiny::fromInt(0);
$c = IntTiny::fromInt(127);

expect($a->value())->toBe(-128)
->and($a->toString())->toBe('-128')
->and($b->value())->toBe(0)
->and($b->toString())->toBe('0')
->and($c->value())->toBe(127)
->and($c->toString())->toBe('127');
});

it('fromString parses integers and enforces tinyint bounds', function (): void {
$v = IntTiny::fromString('-5');
expect($v->value())->toBe(-5)
->and($v->toString())->toBe('-5');
});

it('throws when value is below -128', function (): void {
expect(fn() => new IntTiny(-129))
->toThrow(IntegerTypeException::class, 'Expected tiny integer in range -128..127, got "-129"');
});

it('throws when value is above 127', function (): void {
expect(fn() => IntTiny::fromInt(128))
->toThrow(IntegerTypeException::class, 'Expected tiny integer in range -128..127, got "128"');
});

it('fromString throws on non-integer strings (strict check)', function (): void {
expect(fn() => IntTiny::fromString('12.3'))
->toThrow(IntegerTypeException::class, 'String "12.3" has no valid integer value');
});