Skip to content

Commit

Permalink
refactor: Logger replaced by smart error triggering
Browse files Browse the repository at this point in the history
  • Loading branch information
petrknap committed May 28, 2024
1 parent 5bc477f commit fd2e97a
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 51 deletions.
3 changes: 1 addition & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
"license": "LGPL-3.0-or-later",
"name": "petrknap/optional",
"require": {
"php": ">=8.1",
"psr/log": "^3.0|^2.0|^1.0"
"php": ">=8.1"
},
"require-dev": {
"nunomaduro/phpinsights": "^2.11",
Expand Down
39 changes: 0 additions & 39 deletions src/Logger.php

This file was deleted.

20 changes: 15 additions & 5 deletions src/Optional.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace PetrKnap\Optional;

use Exception;
use InvalidArgumentException;
use Throwable;

Expand All @@ -14,8 +15,6 @@
*/
abstract class Optional implements JavaSe8\Optional
{
use Logger;

private bool|null $wasPresent = null;

/**
Expand All @@ -24,7 +23,7 @@ abstract class Optional implements JavaSe8\Optional
final protected function __construct(
protected readonly mixed $value,
) {
if ($this->value !== null && !static::isSupported($this->value)) {
if ($this->value !== null && !@static::isSupported($this->value)) {
throw new InvalidArgumentException('Value is not supported.');
}
}
Expand Down Expand Up @@ -68,7 +67,7 @@ public static function ofNullable(mixed $value): static
return new class ($value) extends Optional { # @phpstan-ignore-line
protected static function isSupported(mixed $value): bool
{
self::logNotice(Optional::class . ' does not check the type of value.');
TypedOptional::triggerNotice(Optional::class . ' does not check the type of value.');
return true;
}
};
Expand Down Expand Up @@ -113,7 +112,7 @@ public function flatMap(callable $mapper): self # @phpstan-ignore-line
public function get(): mixed
{
if ($this->wasPresent === null) {
self::logNotice('Call `isPresent()` before accessing the value.');
self::triggerNotice('Call `isPresent()` before accessing the value.');
}
return $this->orElseThrow();
}
Expand Down Expand Up @@ -171,4 +170,15 @@ public function orElseThrow(?callable $exceptionSupplier = null): mixed
* @param mixed $value not null
*/
abstract protected static function isSupported(mixed $value): bool;

/**
* @see TypedOptional::triggerNotice()
*/
private static function triggerNotice(string $message): void
{
trigger_error(
$message,
error_level: E_USER_NOTICE,
);
}
}
2 changes: 1 addition & 1 deletion src/OptionalObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static function ofNullable(mixed $value): static
return new class ($value) extends OptionalObject { # @phpstan-ignore-line
protected static function getInstanceOf(): string
{
self::logNotice(OptionalObject::class . ' does not check the instance of object.');
TypedOptional::triggerNotice(OptionalObject::class . ' does not check the instance of object.');
/** @var class-string */
return self::ANY_INSTANCE_OF;
}
Expand Down
2 changes: 1 addition & 1 deletion src/OptionalResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static function ofNullable(mixed $value): static
return new class ($value) extends OptionalResource { # @phpstan-ignore-line
protected static function getResourceType(): string
{
self::logNotice(OptionalResource::class . ' does not check the type of resource.');
TypedOptional::triggerNotice(OptionalResource::class . ' does not check the type of resource.');
/** @var non-empty-string */
return self::ANY_RESOURCE_TYPE;
}
Expand Down
25 changes: 25 additions & 0 deletions src/TypedOptional.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

final class TypedOptional
{
private static bool|null $enabledErrorTriggering = null;

/** @var array<class-string> must be iterated in reverse order */
private static array $typedOptionals = [
OptionalArray::class,
Expand Down Expand Up @@ -58,6 +60,29 @@ public static function register(string $typedOptionalClassName): void
if (!is_a($typedOptionalClassName, Optional::class, allow_string: true)) {
throw new Exception\CouldNotRegisterNonOptional($typedOptionalClassName);
}
if (self::$enabledErrorTriggering === null) {
self::triggerErrors();
}
self::$typedOptionals[] = $typedOptionalClassName;
}

public static function triggerErrors(): void
{
self::$enabledErrorTriggering = true;
}

public static function doNotTriggerErrors(): void
{
self::$enabledErrorTriggering = false;
}

public static function triggerNotice(string $message): void
{
if (self::$enabledErrorTriggering === true) {
trigger_error(
$message,
error_level: E_USER_NOTICE,
);
}
}
}
19 changes: 18 additions & 1 deletion tests/OptionalResourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,24 @@ public function testUsesCorrectType()
{
self::assertInstanceOf(
OptionalResource\OptionalStream::class,
OptionalResource::of(tmpfile()),
OptionalResource::of(fopen('php://memory', 'rw')),
);
}

public function testEqualResourcesAreEqual(): void
{
$r = fopen('php://memory', 'rw');
$a = OptionalResource::of($r);
$b = OptionalResource::of($r);

self::assertTrue($a->equals($b));
}

public function testDifferentResourcesAreNotEqual(): void
{
$a = OptionalResource::of(fopen('php://memory', 'rw'));
$b = OptionalResource::of(fopen('php://memory', 'rw'));

self::assertFalse($a->equals($b));
}
}
4 changes: 2 additions & 2 deletions tests/TypedOptionalsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ public static function dataCouldBeCreated(): array
// Non-scalars
'array' => [OptionalArray::class, []],
'object' => [OptionalObject::class, new stdClass(), ['object(stdClass)']],
'resource' => [OptionalResource::class, tmpfile(), ['resource(stream)']],
'resource' => [OptionalResource::class, fopen('php://memory', 'rw'), ['resource(stream)']],
// Objects
'object(stdClass)' => [OptionalObject\OptionalStdClass::class, new stdClass(), ['object']],
// Resources
'resource(stream)' => [OptionalResource\OptionalStream::class, tmpfile(), ['resource']],
'resource(stream)' => [OptionalResource\OptionalStream::class, fopen('php://memory', 'rw'), ['resource']],
];
}

Expand Down

0 comments on commit fd2e97a

Please sign in to comment.