1
0
mirror of https://github.com/danog/file.git synced 2025-01-22 13:21:13 +01:00

Make further use of PHP 8.1 features

This commit is contained in:
Aaron Piotrowski 2023-01-08 10:16:49 -06:00
parent db002ce874
commit 47277f7f16
No known key found for this signature in database
GPG Key ID: 5B456E6AABA44A63
12 changed files with 96 additions and 107 deletions

View File

@ -18,8 +18,8 @@ final class BlockingFile implements File, \IteratorAggregate
/** @var resource|null */
private $handle;
private string $path;
private string $mode;
private int $id;
private readonly DeferredFuture $onClose;
@ -28,11 +28,13 @@ final class BlockingFile implements File, \IteratorAggregate
* @param string $path File path.
* @param string $mode File open mode.
*/
public function __construct($handle, string $path, string $mode)
{
public function __construct(
$handle,
private readonly string $path,
private readonly string $mode,
) {
$this->handle = $handle;
$this->path = $path;
$this->mode = $mode;
$this->id = (int) $handle;
if ($mode[0] === 'a') {
\fseek($this->handle, 0, \SEEK_END);
@ -44,7 +46,7 @@ final class BlockingFile implements File, \IteratorAggregate
public function __destruct()
{
if ($this->handle !== null) {
@\fclose($this->handle);
\fclose($this->handle);
}
if (!$this->onClose->isComplete()) {
@ -59,7 +61,7 @@ final class BlockingFile implements File, \IteratorAggregate
}
try {
\set_error_handler(function ($type, $message) {
\set_error_handler(function (int $type, string $message): never {
throw new StreamException("Failed reading from file '{$this->path}': {$message}");
});
@ -81,7 +83,7 @@ final class BlockingFile implements File, \IteratorAggregate
}
try {
\set_error_handler(function ($type, $message) {
\set_error_handler(function (int $type, string $message): never {
throw new StreamException("Failed writing to file '{$this->path}': {$message}");
});
@ -117,7 +119,7 @@ final class BlockingFile implements File, \IteratorAggregate
}
try {
\set_error_handler(function ($type, $message) {
\set_error_handler(function (int $type, string $message): never {
throw new StreamException("Failed closing file '{$this->path}': {$message}");
});
@ -148,7 +150,7 @@ final class BlockingFile implements File, \IteratorAggregate
}
try {
\set_error_handler(function ($type, $message) {
\set_error_handler(function (int $type, string $message): never {
throw new StreamException("Could not truncate file '{$this->path}': {$message}");
});
@ -171,7 +173,7 @@ final class BlockingFile implements File, \IteratorAggregate
case self::SEEK_CUR:
case self::SEEK_END:
try {
\set_error_handler(function ($type, $message) {
\set_error_handler(function (int $type, string $message): never {
throw new StreamException("Could not seek in file '{$this->path}': {$message}");
});
@ -230,4 +232,9 @@ final class BlockingFile implements File, \IteratorAggregate
{
return $this->handle !== null && $this->mode[0] !== 'r';
}
public function getId(): int
{
return $this->id;
}
}

View File

@ -2,13 +2,19 @@
namespace Amp\File\Driver;
use Amp\File\File;
use Amp\File\FilesystemDriver;
use Amp\File\FilesystemException;
final class BlockingFilesystemDriver implements FilesystemDriver
{
public function openFile(string $path, string $mode): File
private readonly \Closure $errorHandler;
public function __construct()
{
$this->errorHandler = static fn () => true;
}
public function openFile(string $path, string $mode): BlockingFile
{
$mode = \str_replace(['b', 't', 'e'], '', $mode);
@ -30,7 +36,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
}
try {
\set_error_handler(static function ($type, $message) use ($path, $mode) {
\set_error_handler(static function (int $type, string $message) use ($path, $mode): never {
throw new FilesystemException("Failed to open '{$path}' in mode '{$mode}': {$message}");
});
@ -47,21 +53,31 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function getStatus(string $path): ?array
{
\clearstatcache(true, $path);
\set_error_handler($this->errorHandler);
return @\stat($path) ?: null;
try {
return \stat($path) ?: null;
} finally {
\restore_error_handler();
}
}
public function getLinkStatus(string $path): ?array
{
\clearstatcache(true, $path);
\set_error_handler($this->errorHandler);
return @\lstat($path) ?: null;
try {
return \lstat($path) ?: null;
} finally {
\restore_error_handler();
}
}
public function createSymlink(string $target, string $link): void
{
try {
\set_error_handler(static function ($type, $message) use ($target, $link) {
\set_error_handler(static function (int $type, string $message) use ($target, $link): never {
throw new FilesystemException("Could not create symbolic link '{$link}' to '{$target}': {$message}");
});
@ -76,7 +92,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function createHardlink(string $target, string $link): void
{
try {
\set_error_handler(static function ($type, $message) use ($target, $link) {
\set_error_handler(static function (int $type, string $message) use ($target, $link): never {
throw new FilesystemException("Could not create hard link '{$link}' to '{$target}': {$message}");
});
@ -91,7 +107,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function resolveSymlink(string $target): string
{
try {
\set_error_handler(static function ($type, $message) use ($target) {
\set_error_handler(static function (int $type, string $message) use ($target): never {
throw new FilesystemException("Could not resolve symbolic link '{$target}': {$message}");
});
@ -108,7 +124,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function move(string $from, string $to): void
{
try {
\set_error_handler(static function ($type, $message) use ($from, $to) {
\set_error_handler(static function (int $type, string $message) use ($from, $to): never {
throw new FilesystemException("Could not move file from '{$from}' to '{$to}': {$message}");
});
@ -123,7 +139,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function deleteFile(string $path): void
{
try {
\set_error_handler(static function ($type, $message) use ($path) {
\set_error_handler(static function (int $type, string $message) use ($path): never {
throw new FilesystemException("Could not delete file '{$path}': {$message}");
});
@ -138,7 +154,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function createDirectory(string $path, int $mode = 0777): void
{
try {
\set_error_handler(static function ($type, $message) use ($path) {
\set_error_handler(static function (int $type, string $message) use ($path): never {
throw new FilesystemException("Could not create directory '{$path}': {$message}");
});
@ -154,7 +170,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function createDirectoryRecursively(string $path, int $mode = 0777): void
{
try {
\set_error_handler(static function ($type, $message) use ($path) {
\set_error_handler(static function (int $type, string $message) use ($path): bool {
if (!\is_dir($path)) {
throw new FilesystemException("Could not create directory '{$path}': {$message}");
}
@ -182,7 +198,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function deleteDirectory(string $path): void
{
try {
\set_error_handler(static function ($type, $message) use ($path) {
\set_error_handler(static function (int $type, string $message) use ($path): never {
throw new FilesystemException("Could not remove directory '{$path}': {$message}");
});
@ -197,7 +213,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function listFiles(string $path): array
{
try {
\set_error_handler(static function ($type, $message) use ($path) {
\set_error_handler(static function (int $type, string $message) use ($path): never {
throw new FilesystemException("Failed to list files in '{$path}': {$message}");
});
@ -208,7 +224,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
if ($arr = \scandir($path)) {
\clearstatcache(true, $path);
return \array_values(\array_filter($arr, static function ($el) {
return \array_values(\array_filter($arr, static function ($el): bool {
return $el !== "." && $el !== "..";
}));
}
@ -222,7 +238,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function changePermissions(string $path, int $mode): void
{
try {
\set_error_handler(static function ($type, $message) use ($path) {
\set_error_handler(static function (int $type, string $message) use ($path): never {
throw new FilesystemException("Failed to change permissions for '{$path}': {$message}");
});
@ -237,7 +253,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function changeOwner(string $path, ?int $uid, ?int $gid): void
{
try {
\set_error_handler(static function ($type, $message) use ($path) {
\set_error_handler(static function (int $type, string $message) use ($path): never {
throw new FilesystemException("Failed to change owner for '{$path}': {$message}");
});
@ -259,7 +275,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function touch(string $path, ?int $modificationTime, ?int $accessTime): void
{
try {
\set_error_handler(static function ($type, $message) use ($path) {
\set_error_handler(static function (int $type, string $message) use ($path): never {
throw new FilesystemException("Failed to touch '{$path}': {$message}");
});
@ -277,7 +293,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function read(string $path): string
{
try {
\set_error_handler(static function ($type, $message) use ($path) {
\set_error_handler(static function (int $type, string $message) use ($path): never {
throw new FilesystemException("Failed to read '{$path}': {$message}");
});
@ -294,7 +310,7 @@ final class BlockingFilesystemDriver implements FilesystemDriver
public function write(string $path, string $contents): void
{
try {
\set_error_handler(static function ($type, $message) use ($path) {
\set_error_handler(static function (int $type, string $message) use ($path): never {
throw new FilesystemException("Failed to write to '{$path}': {$message}");
});

View File

@ -3,7 +3,6 @@
namespace Amp\File\Driver;
use Amp\DeferredFuture;
use Amp\File\File;
use Amp\File\FilesystemDriver;
use Amp\File\FilesystemException;
use Amp\File\Internal;
@ -26,7 +25,7 @@ final class EioFilesystemDriver implements FilesystemDriver
$this->poll = new Internal\EioPoll($driver);
}
public function openFile(string $path, string $mode): File
public function openFile(string $path, string $mode): EioFile
{
$flags = \EIO_O_NONBLOCK | $this->parseMode($mode);
if (\defined('\EIO_O_FSYNC')) {

View File

@ -23,37 +23,33 @@ final class ParallelFile implements File, \IteratorAggregate
{
use ReadableStreamIteratorAggregate;
private readonly Internal\FileWorker $worker;
private ?int $id;
private string $path;
private int $position;
private int $size;
private string $mode;
/** @var bool True if an operation is pending. */
private bool $busy = false;
/** @var int Number of pending write operations. */
private int $pendingWrites = 0;
private bool $writable = true;
private bool $writable;
private ?Future $closing = null;
private readonly DeferredFuture $onClose;
public function __construct(Internal\FileWorker $worker, int $id, string $path, int $size, string $mode)
{
$this->worker = $worker;
public function __construct(
private readonly Internal\FileWorker $worker,
int $id,
private readonly string $path,
int $size,
private readonly string $mode,
) {
$this->id = $id;
$this->path = $path;
$this->size = $size;
$this->mode = $mode;
$this->writable = $this->mode[0] !== 'r';
$this->position = $this->mode[0] === 'a' ? $this->size : 0;
@ -158,7 +154,7 @@ final class ParallelFile implements File, \IteratorAggregate
$this->busy = true;
try {
$data = $this->worker->execute(new Internal\FileTask('fread', [null, $length], $this->id), $cancellation);
$data = $this->worker->execute(new Internal\FileTask('fread', [$length], $this->id), $cancellation);
if ($data !== null) {
$this->position += \strlen($data);

View File

@ -2,7 +2,6 @@
namespace Amp\File\Driver;
use Amp\File\File;
use Amp\File\FilesystemDriver;
use Amp\File\FilesystemException;
use Amp\File\Internal;
@ -40,7 +39,7 @@ final class ParallelFilesystemDriver implements FilesystemDriver
$this->pendingWorker = Future::complete();
}
public function openFile(string $path, string $mode): File
public function openFile(string $path, string $mode): ParallelFile
{
$worker = $this->selectWorker();

View File

@ -2,7 +2,6 @@
namespace Amp\File\Driver;
use Amp\File\File;
use Amp\File\FilesystemDriver;
use Amp\File\Internal\Cache;
@ -18,7 +17,7 @@ final class StatusCachingFilesystemDriver implements FilesystemDriver
$this->statusCache = new Cache(1000, 1024);
}
public function openFile(string $path, string $mode): File
public function openFile(string $path, string $mode): StatusCachingFile
{
$file = $this->driver->openFile($path, $mode);

View File

@ -4,7 +4,6 @@
namespace Amp\File\Driver;
use Amp\DeferredFuture;
use Amp\File\File;
use Amp\File\FilesystemDriver;
use Amp\File\FilesystemException;
use Amp\File\Internal;
@ -23,8 +22,6 @@ final class UvFilesystemDriver implements FilesystemDriver
return $driver instanceof UvLoopDriver;
}
private readonly UvLoopDriver $driver;
/** @var \UVLoop|resource Loop resource of type uv_loop or instance of \UVLoop. */
private $eventLoopHandle;
@ -33,17 +30,15 @@ final class UvFilesystemDriver implements FilesystemDriver
/** @var bool True if ext-uv version is < 0.3.0. */
private readonly bool $priorVersion;
public function __construct(UvLoopDriver $driver)
public function __construct(private readonly UvLoopDriver $driver)
{
$this->driver = $driver;
/** @psalm-suppress PropertyTypeCoercion */
$this->eventLoopHandle = $driver->getHandle();
$this->poll = new Internal\UvPoll($driver);
$this->priorVersion = \version_compare(\phpversion('uv'), '0.3.0', '<');
}
public function openFile(string $path, string $mode): File
public function openFile(string $path, string $mode): UvFile
{
$flags = $this->parseMode($mode);
$chmod = ($flags & \UV::O_CREAT) ? 0644 : 0;
@ -252,7 +247,7 @@ final class UvFilesystemDriver implements FilesystemDriver
&$tmpPath,
$mode,
$deferred
) {
): void {
$tmpPath .= DIRECTORY_SEPARATOR . \array_shift($arrayPath);
if (empty($arrayPath)) {
@ -449,28 +444,17 @@ final class UvFilesystemDriver implements FilesystemDriver
{
$mode = \str_replace(['b', 't', 'e'], '', $mode);
switch ($mode) {
case "r":
return \UV::O_RDONLY;
case "r+":
return \UV::O_RDWR;
case "c":
case "w":
return \UV::O_WRONLY | \UV::O_CREAT;
case "c+":
case "w+":
return \UV::O_RDWR | \UV::O_CREAT;
case "a":
return \UV::O_WRONLY | \UV::O_CREAT | \UV::O_APPEND;
case "a+":
return \UV::O_RDWR | \UV::O_CREAT | \UV::O_APPEND;
case "x":
return \UV::O_WRONLY | \UV::O_CREAT | \UV::O_EXCL;
case "x+":
return \UV::O_RDWR | \UV::O_CREAT | \UV::O_EXCL;
default:
throw new \Error('Invalid file mode');
}
return match ($mode) {
"r" => \UV::O_RDONLY,
"r+" => \UV::O_RDWR,
"c", "w" => \UV::O_WRONLY | \UV::O_CREAT,
"c+", "w+" => \UV::O_RDWR | \UV::O_CREAT,
"a" => \UV::O_WRONLY | \UV::O_CREAT | \UV::O_APPEND,
"a+" => \UV::O_RDWR | \UV::O_CREAT | \UV::O_APPEND,
"x" => \UV::O_WRONLY | \UV::O_CREAT | \UV::O_EXCL,
"x+" => \UV::O_RDWR | \UV::O_CREAT | \UV::O_EXCL,
default => throw new \Error('Invalid file mode'),
};
}
private function onOpenHandle(mixed $fileHandle, string $mode, string $path, DeferredFuture $deferred): void

View File

@ -11,15 +11,11 @@ final class FileMutex implements Mutex
{
private const LATENCY_TIMEOUT = 0.01;
/** @var string The full path to the lock file. */
private string $fileName;
/**
* @param string $fileName Name of temporary file to use as a mutex.
*/
public function __construct(string $fileName)
public function __construct(private readonly string $fileName)
{
$this->fileName = $fileName;
}
public function acquire(): Lock
@ -31,7 +27,7 @@ final class FileMutex implements Mutex
$file = openFile($this->fileName, 'x');
// Return a lock object that can be used to release the lock on the mutex.
$lock = new Lock(fn () => $this->release());
$lock = new Lock($this->release(...));
$file->close();

View File

@ -7,21 +7,19 @@ use Revolt\EventLoop;
/** @internal */
final class Cache
{
private object $sharedState;
private readonly object $sharedState;
private string $ttlWatcherId;
private ?int $maxSize;
private readonly string $ttlWatcherId;
/**
* @param int $gcInterval The frequency in milliseconds at which expired cache entries should be garbage
* collected.
* @param int|null $maxSize The maximum size of cache array (number of elements).
*/
public function __construct(int $gcInterval = 1000, ?int $maxSize = null)
public function __construct(int $gcInterval = 1000, private readonly ?int $maxSize = null)
{
// By using a shared state object we're able to use `__destruct()` for "normal" garbage collection of both this
// instance and the loop's watcher. Otherwise this object could only be GC'd when the TTL watcher was cancelled
// instance and the loop's watcher. Otherwise, this object could only be GC'd when the TTL watcher was cancelled
// at the loop layer.
$this->sharedState = $sharedState = new class {
/** @var array[] */
@ -53,8 +51,7 @@ final class Cache
}
};
$this->ttlWatcherId = EventLoop::repeat($gcInterval, \Closure::fromCallable([$sharedState, "collectGarbage"]));
$this->maxSize = $maxSize;
$this->ttlWatcherId = EventLoop::repeat($gcInterval, $sharedState->collectGarbage(...));
EventLoop::unreference($this->ttlWatcherId);
}

View File

@ -10,11 +10,11 @@ final class EioPoll
/** @var resource */
private static $stream;
private string $watcher;
private readonly string $watcher;
private int $requests = 0;
public function __construct(private EventLoopDriver $driver)
public function __construct(private readonly EventLoopDriver $driver)
{
if (!self::$stream) {
if (\function_exists('eio_init')) {

View File

@ -9,17 +9,13 @@ use Amp\Parallel\Worker\Worker;
/** @internal */
final class FileWorker
{
private \Closure $push;
private Worker $worker;
/**
* @param \Closure(Worker):void $push Closure to push the worker back into the queue.
*/
public function __construct(Worker $worker, \Closure $push)
{
$this->worker = $worker;
$this->push = $push;
public function __construct(
private readonly Worker $worker,
private readonly \Closure $push
) {
}
/**

View File

@ -7,11 +7,11 @@ use Revolt\EventLoop\Driver\UvDriver as UvLoopDriver;
/** @internal */
final class UvPoll
{
private string $watcher;
private readonly string $watcher;
private int $requests = 0;
public function __construct(private UvLoopDriver $driver)
public function __construct(private readonly UvLoopDriver $driver)
{
// Create dummy watcher to keep loop running while polling.