diff --git a/proofs/file/content.php b/proofs/file/content.php index 046a468..734c346 100644 --- a/proofs/file/content.php +++ b/proofs/file/content.php @@ -95,7 +95,7 @@ static function($assert) use ($io) { )); $count = 0; - $content->foreach(static function() use (&$count) { + $_ = $content->foreach(static function() use (&$count) { $count++; }); diff --git a/properties/Adapter/AddDirectory.php b/properties/Adapter/AddDirectory.php index 9ae290e..5e7ae70 100644 --- a/properties/Adapter/AddDirectory.php +++ b/properties/Adapter/AddDirectory.php @@ -80,7 +80,7 @@ private function assertSame( } if ($target instanceof Directory) { - $target->foreach(function($file) use ($assert, $source) { + $_ = $target->foreach(function($file) use ($assert, $source) { $assert->true($source->contains($file->name())); $this->assertSame( diff --git a/properties/Content/ForeachExposeAllLines.php b/properties/Content/ForeachExposeAllLines.php index 59d9dd9..a6ec808 100644 --- a/properties/Content/ForeachExposeAllLines.php +++ b/properties/Content/ForeachExposeAllLines.php @@ -31,7 +31,7 @@ public function applicableTo(object $systemUnderTest): bool public function ensureHeldBy(Assert $assert, object $systemUnderTest): object { $count = 0; - $systemUnderTest->foreach(static function($line) use ($assert, &$count) { + $_ = $systemUnderTest->foreach(static function($line) use ($assert, &$count) { $assert->object($line)->instance(Line::class); $count++; }); diff --git a/properties/Directory/AllFilesInTheDirectoryAreAccessible.php b/properties/Directory/AllFilesInTheDirectoryAreAccessible.php index 4d3e78c..4a03048 100644 --- a/properties/Directory/AllFilesInTheDirectoryAreAccessible.php +++ b/properties/Directory/AllFilesInTheDirectoryAreAccessible.php @@ -27,7 +27,7 @@ public function applicableTo(object $directory): bool public function ensureHeldBy(Assert $assert, object $directory): object { - $directory->foreach(static function($file) use ($assert, $directory) { + $_ = $directory->foreach(static function($file) use ($assert, $directory) { $assert->same( $file->name(), $directory->get($file->name())->match( diff --git a/properties/Directory/ContainsMethodAlwaysReturnTrueForFilesInTheDirectory.php b/properties/Directory/ContainsMethodAlwaysReturnTrueForFilesInTheDirectory.php index 6862dd2..4f73186 100644 --- a/properties/Directory/ContainsMethodAlwaysReturnTrueForFilesInTheDirectory.php +++ b/properties/Directory/ContainsMethodAlwaysReturnTrueForFilesInTheDirectory.php @@ -27,7 +27,7 @@ public function applicableTo(object $directory): bool public function ensureHeldBy(Assert $assert, object $directory): object { - $directory->foreach(static function($file) use ($assert, $directory) { + $_ = $directory->foreach(static function($file) use ($assert, $directory) { $assert->true($directory->contains($file->name())); }); diff --git a/properties/Directory/FilteringDoesntAffectTheDirectory.php b/properties/Directory/FilteringDoesntAffectTheDirectory.php index 2cdd025..b37d0dd 100644 --- a/properties/Directory/FilteringDoesntAffectTheDirectory.php +++ b/properties/Directory/FilteringDoesntAffectTheDirectory.php @@ -30,9 +30,9 @@ public function ensureHeldBy(Assert $assert, object $directory): object $all = $directory->filter(static fn(): bool => true); $none = $directory->filter(static fn(): bool => false); - $directory->foreach(static fn($file) => $assert->false($none->contains($file->name()))); - $directory->foreach(static fn($file) => $assert->true($all->contains($file->name()))); - $all->foreach(static fn($file) => $assert->true($directory->contains($file->name()))); + $_ = $directory->foreach(static fn($file) => $assert->false($none->contains($file->name()))); + $_ = $directory->foreach(static fn($file) => $assert->true($all->contains($file->name()))); + $_ = $all->foreach(static fn($file) => $assert->true($directory->contains($file->name()))); $assert->same($directory->removed(), $all->removed()); $assert->same($directory->removed(), $none->removed()); diff --git a/psalm.xml b/psalm.xml index 5d768ff..a270b9b 100644 --- a/psalm.xml +++ b/psalm.xml @@ -14,4 +14,7 @@ + + + diff --git a/src/Adapter.php b/src/Adapter.php index 53a9c21..cc1045d 100644 --- a/src/Adapter.php +++ b/src/Adapter.php @@ -42,6 +42,7 @@ private function __construct( /** * @return Attempt */ + #[\NoDiscard] public static function mount( Path $path, CaseSensitivity $case = CaseSensitivity::sensitive, @@ -65,6 +66,7 @@ public static function mount( }); } + #[\NoDiscard] public static function inMemory(): self { return new self( @@ -73,6 +75,7 @@ public static function inMemory(): self ); } + #[\NoDiscard] public static function logger( self $adapter, LoggerInterface $logger, @@ -86,6 +89,7 @@ public static function logger( /** * @return Attempt */ + #[\NoDiscard] public function add(File|Directory $file): Attempt { return $this->write(TreePath::root(), $file); @@ -94,6 +98,7 @@ public function add(File|Directory $file): Attempt /** * @return Maybe */ + #[\NoDiscard] public function get(Name $file): Maybe { return $this->access( @@ -102,6 +107,7 @@ public function get(Name $file): Maybe ); } + #[\NoDiscard] public function contains(Name $file): bool { return $this->implementation->exists(TreePath::of($file))->match( @@ -113,11 +119,13 @@ public function contains(Name $file): bool /** * @return Attempt */ + #[\NoDiscard] public function remove(Name $file): Attempt { return $this->implementation->remove(TreePath::root(), $file); } + #[\NoDiscard] public function root(): Directory { $root = TreePath::root(); diff --git a/src/Directory.php b/src/Directory.php index 63ce2ca..6184f5e 100644 --- a/src/Directory.php +++ b/src/Directory.php @@ -31,6 +31,7 @@ private function __construct( * * @param Sequence|null $files */ + #[\NoDiscard] public static function of(Name $name, ?Sequence $files = null): self { return new self( @@ -46,6 +47,7 @@ public static function of(Name $name, ?Sequence $files = null): self * @param non-empty-string $name * @param Sequence|null $files */ + #[\NoDiscard] public static function named(string $name, ?Sequence $files = null): self { return new self( @@ -61,6 +63,7 @@ public static function named(string $name, ?Sequence $files = null): self * * @param Sequence $files */ + #[\NoDiscard] public static function lazy(Name $name, Sequence $files): self { // we prevent the contrusctor from checking for duplicates when @@ -71,11 +74,13 @@ public static function lazy(Name $name, Sequence $files): self return new self($name, $files, Set::of()); } + #[\NoDiscard] public function name(): Name { return $this->name; } + #[\NoDiscard] public function rename(Name $name): self { return new self( @@ -85,6 +90,7 @@ public function rename(Name $name): self ); } + #[\NoDiscard] public function add(File|self $file): self { return new self( @@ -100,11 +106,13 @@ public function add(File|self $file): self /** * @return Maybe */ + #[\NoDiscard] public function get(Name $name): Maybe { return $this->files->find(static fn($file) => $file->name()->equals($name)); } + #[\NoDiscard] public function contains(Name $name): bool { return $this->get($name)->match( @@ -113,6 +121,7 @@ public function contains(Name $name): bool ); } + #[\NoDiscard] public function remove(Name $name): self { return new self( @@ -125,6 +134,7 @@ public function remove(Name $name): self /** * @param callable(File|self): void $function */ + #[\NoDiscard] public function foreach(callable $function): SideEffect { return $this->files->foreach($function); @@ -133,6 +143,7 @@ public function foreach(callable $function): SideEffect /** * @param callable(File|self): bool $predicate */ + #[\NoDiscard] public function filter(callable $predicate): self { // it is safe to not check for duplicates here as either the current @@ -150,6 +161,7 @@ public function filter(callable $predicate): self /** * @param callable(File|self): File $map */ + #[\NoDiscard] public function map(callable $map): self { return new self( @@ -162,6 +174,7 @@ public function map(callable $map): self /** * @param callable(File|self): self $map */ + #[\NoDiscard] public function flatMap(callable $map): self { /** @var callable(File|self): Sequence */ @@ -182,6 +195,7 @@ public function flatMap(callable $map): self * * @return R */ + #[\NoDiscard] public function reduce($carry, callable $reducer) { return $this->files->reduce($carry, $reducer); @@ -195,6 +209,7 @@ public function reduce($carry, callable $reducer) * * @return Set */ + #[\NoDiscard] public function removed(): Set { return $this->removed; @@ -203,6 +218,7 @@ public function removed(): Set /** * @return Sequence */ + #[\NoDiscard] public function all(): Sequence { return $this->files; diff --git a/src/Exception/MountPathDoesntExist.php b/src/Exception/MountPathDoesntExist.php index 2c53a6f..8b8c75d 100644 --- a/src/Exception/MountPathDoesntExist.php +++ b/src/Exception/MountPathDoesntExist.php @@ -22,6 +22,7 @@ public function __construct( /** * @return Attempt */ + #[\NoDiscard] public function recover(): Attempt { return ($this->recover)(); diff --git a/src/Exception/RecoverMount.php b/src/Exception/RecoverMount.php index a2764ec..d02d405 100644 --- a/src/Exception/RecoverMount.php +++ b/src/Exception/RecoverMount.php @@ -22,6 +22,7 @@ public function __construct( /** * @return Attempt */ + #[\NoDiscard] public function recover(): Attempt { return ($this->recover)(); diff --git a/src/File.php b/src/File.php index bc0470f..f6c643e 100644 --- a/src/File.php +++ b/src/File.php @@ -21,6 +21,7 @@ private function __construct( /** * @psalm-pure */ + #[\NoDiscard] public static function of( Name $name, Content $content, @@ -34,6 +35,7 @@ public static function of( * * @param non-empty-string $name */ + #[\NoDiscard] public static function named( string $name, Content $content, @@ -42,26 +44,31 @@ public static function named( return self::of(Name::of($name), $content, $mediaType); } + #[\NoDiscard] public function name(): Name { return $this->name; } + #[\NoDiscard] public function content(): Content { return $this->content; } + #[\NoDiscard] public function mediaType(): MediaType { return $this->mediaType; } + #[\NoDiscard] public function rename(Name $name): self { return new self($name, $this->content, $this->mediaType); } + #[\NoDiscard] public function withContent(Content $content, ?MediaType $mediaType = null): self { return new self( @@ -74,6 +81,7 @@ public function withContent(Content $content, ?MediaType $mediaType = null): sel /** * @param callable(Content): Content $map */ + #[\NoDiscard] public function mapContent(callable $map): self { /** @psalm-suppress ImpureFunctionCall */ diff --git a/src/File/Content.php b/src/File/Content.php index 22e0ba0..b353afa 100644 --- a/src/File/Content.php +++ b/src/File/Content.php @@ -31,6 +31,7 @@ private function __construct(private Implementation $implementation) /** * @psalm-pure */ + #[\NoDiscard] public static function io(Stream|Read $io): self { return new self(Content\IO::of($io)); @@ -41,6 +42,7 @@ public static function io(Stream|Read $io): self * * This method is to be used with sockets that can't be read twice */ + #[\NoDiscard] public static function oneShot(Stream $io): self { return new self(Content\OneShot::of($io)); @@ -51,6 +53,7 @@ public static function oneShot(Stream $io): self * * @param Sequence $chunks */ + #[\NoDiscard] public static function ofChunks(Sequence $chunks): self { return new self(Content\Chunks::of($chunks)); @@ -61,6 +64,7 @@ public static function ofChunks(Sequence $chunks): self * * @param Sequence $lines */ + #[\NoDiscard] public static function ofLines(Sequence $lines): self { return new self(Content\Lines::of($lines)); @@ -69,6 +73,7 @@ public static function ofLines(Sequence $lines): self /** * @psalm-pure */ + #[\NoDiscard] public static function ofString(string $content): self { return self::ofLines( @@ -81,6 +86,7 @@ public static function ofString(string $content): self /** * @psalm-pure */ + #[\NoDiscard] public static function none(): self { return new self(Content\Lines::of(Sequence::of(Line::of(Str::of(''))))); @@ -89,6 +95,7 @@ public static function none(): self /** * @param callable(Line): void $function */ + #[\NoDiscard] public function foreach(callable $function): SideEffect { return $this->implementation->foreach($function); @@ -97,6 +104,7 @@ public function foreach(callable $function): SideEffect /** * @param callable(Line): Line $map */ + #[\NoDiscard] public function map(callable $map): self { return new self($this->implementation->map($map)); @@ -105,6 +113,7 @@ public function map(callable $map): self /** * @param callable(Line): self $map */ + #[\NoDiscard] public function flatMap(callable $map): self { return new self($this->implementation->flatMap($map)); @@ -113,6 +122,7 @@ public function flatMap(callable $map): self /** * @param callable(Line): bool $filter */ + #[\NoDiscard] public function filter(callable $filter): self { return new self($this->implementation->filter($filter)); @@ -121,6 +131,7 @@ public function filter(callable $filter): self /** * @return Sequence */ + #[\NoDiscard] public function lines(): Sequence { return $this->implementation->lines(); @@ -129,6 +140,7 @@ public function lines(): Sequence /** * @return Sequence */ + #[\NoDiscard] public function chunks(): Sequence { return $this->implementation->chunks(); @@ -142,6 +154,7 @@ public function chunks(): Sequence * * @return T */ + #[\NoDiscard] public function reduce($carry, callable $reducer) { return $this->implementation->reduce($carry, $reducer); @@ -150,11 +163,13 @@ public function reduce($carry, callable $reducer) /** * @return Maybe */ + #[\NoDiscard] public function size(): Maybe { return $this->implementation->size(); } + #[\NoDiscard] public function toString(): string { return $this->implementation->toString(); diff --git a/src/File/Content/Line.php b/src/File/Content/Line.php index 5617680..9feb55b 100644 --- a/src/File/Content/Line.php +++ b/src/File/Content/Line.php @@ -17,6 +17,7 @@ private function __construct(private Str $content) /** * @psalm-pure */ + #[\NoDiscard] public static function of(Str $content): self { if ($content->contains("\n")) { @@ -30,6 +31,7 @@ public static function of(Str $content): self * @internal * @psalm-pure */ + #[\NoDiscard] public static function fromStream(Str $content): self { return new self($content->rightTrim("\n")); @@ -38,17 +40,20 @@ public static function fromStream(Str $content): self /** * @param callable(Str): Str $map */ + #[\NoDiscard] public function map(callable $map): self { /** @psalm-suppress ImpureFunctionCall */ return self::of($map($this->content)); } + #[\NoDiscard] public function str(): Str { return $this->content; } + #[\NoDiscard] public function toString(): string { return $this->content->toString(); diff --git a/src/Name.php b/src/Name.php index e285f1a..8341f37 100644 --- a/src/Name.php +++ b/src/Name.php @@ -54,16 +54,19 @@ private function __construct(string $value) * * @throws \DomainException */ + #[\NoDiscard] public static function of(string $value): self { return new self($value); } + #[\NoDiscard] public function equals(self $name): bool { return $this->value === $name->value; } + #[\NoDiscard] public function str(): Str { return Str::of($this->value); @@ -72,6 +75,7 @@ public function str(): Str /** * @return non-empty-string */ + #[\NoDiscard] public function toString(): string { return $this->value; diff --git a/src/Recover.php b/src/Recover.php index ee183e1..6c38af2 100644 --- a/src/Recover.php +++ b/src/Recover.php @@ -15,6 +15,7 @@ private function __construct( /** * @return Attempt */ + #[\NoDiscard] public static function mount(\Throwable $e): Attempt { return match (true) { diff --git a/tests/DirectoryTest.php b/tests/DirectoryTest.php index 72ce96f..4d1a691 100644 --- a/tests/DirectoryTest.php +++ b/tests/DirectoryTest.php @@ -197,7 +197,7 @@ public function testDirectoryLoadedWithDifferentFilesWithTheSameNameThrows() $this->expectException(\LogicException::class); $this->expectExceptionMessage("Same file '{$file->toString()}' found multiple times"); - Directory::of( + $_ = Directory::of( $directory, Sequence::of( File::named($file->toString(), Content::none()), @@ -218,7 +218,7 @@ public function testNamedDirectoryLoadedWithDifferentFilesWithTheSameNameThrows( $this->expectException(\LogicException::class); $this->expectExceptionMessage("Same file '{$file->toString()}' found multiple times"); - Directory::named( + $_ = Directory::named( $directory->toString(), Sequence::of( File::named($file->toString(), Content::none()), diff --git a/tests/File/Content/LineTest.php b/tests/File/Content/LineTest.php index 992cced..53326a1 100644 --- a/tests/File/Content/LineTest.php +++ b/tests/File/Content/LineTest.php @@ -24,7 +24,7 @@ public function testDoesntAcceptNewLineDelimiter() ) ->then(function($start, $end) { try { - Line::of(Str::of($start."\n".$end)); + $_ = Line::of(Str::of($start."\n".$end)); $this->fail('it should throw'); } catch (\Exception $e) { @@ -83,7 +83,7 @@ public function testMappedLineCannotContainEndOfLineDelimiter() $line = Line::of(Str::of($content)); try { - $line->map(static fn($line) => $line->append("\n")); + $_ = $line->map(static fn($line) => $line->append("\n")); $this->fail('it should throw'); } catch (\Exception $e) { diff --git a/tests/NameTest.php b/tests/NameTest.php index 1060ca6..e76695e 100644 --- a/tests/NameTest.php +++ b/tests/NameTest.php @@ -29,7 +29,7 @@ public function testThrowWhenABuildingNameWithASlash() $this->expectException(\DomainException::class); $this->expectExceptionMessage('A file name can\'t contain a slash, foo/bar given'); - Name::of('foo/bar'); + $_ = Name::of('foo/bar'); } public function testEquals() @@ -43,7 +43,7 @@ public function testEmptyNameIsNotAllowed() $this->expectException(\DomainException::class); $this->expectExceptionMessage('A file name can\'t be empty'); - Name::of(''); + $_ = Name::of(''); } public function testAcceptsAnyValueNotContainingASlash() @@ -69,7 +69,7 @@ public function testNameContainingASlashIsNotAccepted() ->then(function($a, $b) { $this->expectException(\DomainException::class); - Name::of("$a/$b"); + $_ = Name::of("$a/$b"); }); } @@ -110,7 +110,7 @@ public function testDotFoldersAreNotAccepted() ->forAll(Set::of('.', '..')) ->then(function($name) { try { - Name::of($name); + $_ = Name::of($name); $this->fail('it should throw'); } catch (\DomainException $e) { @@ -123,7 +123,7 @@ public function testChr0IsNotAccepted() { $this->expectException(\DomainException::class); - Name::of('a'.\chr(0).'a'); + $_ = Name::of('a'.\chr(0).'a'); } public function testNamesLongerThan255AreNotAccepted() @@ -143,7 +143,7 @@ public function testNamesLongerThan255AreNotAccepted() ) ->then(function($name) { try { - Name::of($name); + $_ = Name::of($name); $this->fail('it should throw'); } catch (\Throwable $e) { @@ -161,7 +161,7 @@ public function testNameWithOnlyWhiteSpacesIsNotAccepted() )) ->then(function($ord) { try { - Name::of(\chr($ord)); + $_ = Name::of(\chr($ord)); $this->fail('it should throw'); } catch (\DomainException $e) {